Как проверить, если текущая оболочка zsh уже выполнила команды `dircolors` и` stty`?

Я использую zsh версии 5.3.1:

 % zsh --version zsh 5.3.1 (x86_64-pc-linux-gnu) 

Я пытаюсь определить привязку ключа, используя последовательность ключей Cx r , чтобы перезагрузить конфигурацию zsh . Благодаря @Gilles , я включил этот код в свой ~/.zshrc :

 reread_zshrc () { . ~/.zshrc } zle -N reread_zshrc bindkey '^Xr' reread_zshrc 

Он работает, за исключением того, что когда я нажимаю Cx r , zsh жалуется на ошибки:

 stty: 'standard input': Bad file descriptor stty: 'standard input': Bad file descriptor dircolors: /home/user/.dircolors: Bad file descriptor 

Я могу воспроизвести эти ошибки со следующим минимальным zshrc :

 stty -ixon stty quit undef eval "$(dircolors -b ~/.dircolors)" reread_zshrc () { . ~/.zshrc } zle -N reread_zshrc bindkey '^Xr' reread_zshrc 

Вот почему я включил 2 stty команды и команду dircolors в моем zshrc .

stty -ixon позволяет драйверу терминала интерпретировать Cs и Cq как управление потоком терминала: по умолчанию Cs замораживает терминал и Cq размораживает его. Он позволяет использовать Cs и Cq в Cq клавиш для оболочки или текстового редактора, не замораживая терминал.

stty quit undef позволяет драйверу терминала отправлять сигнал SIGQUIT при нажатии SIGQUIT C-\ . Опять же, он позволяет использовать этот ключ в привязке клавиш без завершения процесса переднего плана.

eval "$(dircolors -b ~/.dircolors)" просит команду ls прочитать ее конфигурацию из ~/.dircolors . Он позволяет настраивать цвета на выходе команды ls .

Полагаю, мне нужно защитить эти 3 строки от повторного получения zsh если они уже были выполнены в текущей оболочке. Но я не знаю, какое условие писать:

 if <stty and dircolors haven't been executed already>; then stty -ixon stty quit undef eval "$(dircolors -b ~/.dircolors)" if 

Кроме того, я хотел бы лучше понять эти сообщения об ошибках, потому что, если я их zsh в интерактивной оболочке zsh , они не вызовут никаких проблем. Почему они только поднимают ошибки из этой привязки ключа.

  • `ls -l` файла и всех каталогов, ведущих к нему?
  • Сочетание вклада вкладки zsh с нечувствительностью к регистру
  • Расширение {a..d} до abcd в zsh
  • Есть ли способ перечислить количество файлов при использовании dpkg -L для отображения файлов пакета?
  • Как указать тайм-аут для завершения вкладки в zsh?
  • сделать мой режим отображения zsh в режиме vi
  • mv * (исключение ошибки «can not move»)
  • oh-my-zsh завершение в именах домашних каталогов
  • One Solution collect form web for “Как проверить, если текущая оболочка zsh уже выполнила команды `dircolors` и` stty`?”

    В zle виджетах, похоже, zsh закрывает stdin. Я предполагаю, что zsh хочет, чтобы команды в этих виджетах не вмешивались непосредственно в пользовательский ввод, но было бы разумнее перенаправить stdin из / dev / null ( это будет исправлено в следующей версии ).

    Когда stdin (дескриптор файла 0) закрыт, это означает, что первый файл, который открывает команда, становится его stdin (поскольку файловые дескрипторы выделены из первого свободного).

    В dircolors это вызывает ошибку. dircolors открывает ваш ~/.dircolors , а затем пытается сделать его своим stdin, не заметив, что это уже был его stdin (потому что это возвращает fd open() ). Таким образом, dup2(0,0) (dup stdin на себя) терпит неудачу с ошибкой EBADF, о которой сообщает dircolors .

    stty устанавливает настройки терминала на его stdin. Здесь stdin закрыт, поэтому stty возвращается с ошибкой.

    Здесь вы можете изменить свой виджет, чтобы он восстанавливал stdin на терминал:

     reread_zshrc () . ~/.zshrc < $TTY 

    Но обратите внимание, что изменение настроек tty из виджета zle (хотя я не знаю, что делает ваша команда stty ) – это плохая идея, так как zle устанавливает tty в специальный режим для редактирования строк, который вы не хотите испортить с (и в конце редактирования нормальные настройки tty будут восстановлены в любом случае, так что сделанные вами изменения будут потеряны).

    Так что, возможно, вместо этого вы должны сделать stdin /dev/null (так как вы действительно не хотите делать что-то с терминалом там), но stty все равно будет жаловаться (поскольку /dev/null не является устройством tty), так что вы можете также хотите перенаправить stderr в / dev / null, чтобы скрыть эти сообщения об ошибках (хотя это скроет все сообщения об ошибках):

     reread_zshrc() . ~/.zshrc < /dev/null 2> /dev/null 
    Interesting Posts

    Получение цифровой подписи с eToken / смарт-карты в LibreOffice

    Объясните команду оболочки: shift $ (($ optind – 1))

    Как «найти» несколько файлов и открыть их в vim?

    неопределенная ссылка на ошибку «curl_free». Не могу найти, что делать

    grepping массив из файла и повторное использование шаблона поиска

    Как открыть VPN-соединение внутри другого VPN-соединения под Linux / Ubuntu

    Существуют ли какие-либо настройки разрешений для проверки атрибутов (rwx) файла?

    Как загрузить архив и извлечь его, не сохраняя архив на диск?

    Скорость колесика мыши слишком чувствительна

    Как мне разрешить права доступа к каталогам и посмотреть, не хватает ли прав на запись?

    Команды Emacs в xterm

    Есть ли способ «меньше» обрезать строки и все равно выйти после <1 экрана?

    Что означает «липкий бит» в NFS?

    Найти самые большие файлы с каждой даты в каталоге

    Как настроить what.localhost.dev для разрешения на 127.0.0.1 на Ubuntu 12.04?

    Linux и Unix - лучшая ОС в мире.