Как проверить, если текущая оболочка 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 , они не вызовут никаких проблем. Почему они только поднимают ошибки из этой привязки ключа.

  • Команда Echo с оператором AND не выходит
  • Расширение поиска истории в zsh
  • Bash и / или Zsh: Возможно ли настроить режим вставки Vi для создания привязки, которая перемещает определенное количество символов?
  • Экспорт РЕДАКТОР с флагом
  • Сократить путь в приглашении zsh
  • Как сделать zsh «правильной» функциональностью, помните мои решения по исправлению заклинаний
  • Что произойдет, если оболочка по умолчанию для пользователей не установлена?
  • Когда я пытаюсь добавить Android SDK в свой PATH, он дает контекстную ошибку
  • 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

    Почему входящие пакеты на интерфейсе TAP видны с помощью tcpdump, но не с iptables?

    Как показать список цитируемых команд?

    Сценарий, чтобы проверить, не вышел ли пользователь

    history – Список только успешно запускает команды

    Сжатие дерева каталогов в нескольких архивах tar в один xz

    grub2 отсутствуют окна, манджаро

    Какова соответствующая ценность vm.swappiness при использовании zram?

    Реализация расширенного регулярного выражения для добавления переменной числа ведущих нулей на основе позиции в строке

    Как разделить список значений на число в командной строке?

    Включить SELinux при загрузке

    sed + добавить комментарий к IP – только если IP точно соответствует

    чтение параллельной обработки из файла в цикле

    создание нового модуля, карта

    Является ли PAM методом аутентификации пользователей?

    Какую программу я могу использовать для получения функций копирования / факса из отдельного сканера и принтера?

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