現在、zshシェルが `dircolors`と`stty`コマンドを実行したかどうかをテストする方法は?

現在、zshシェルが `dircolors`と`stty`コマンドを実行したかどうかをテストする方法は?

バージョン5.3.1を使用していますzsh

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

C-x r設定を再ロードするために、キーシーケンスを使用してキーバインディングを定義しようとしていますzsh。ありがとう@ギルス、私のコードには次のコードが含まれています~/.zshrc

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

をクリックした場合を除いては機能しますが、C-x 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ターミナルドライバがターミナルフロー制御を解釈してC-s動作C-qするのを防ぎます。デフォルトでは、C-s端末を固定してC-q固定を解除します。端末を停止しなくても、シェルまたはテキストエディタのキーバインディングをC-s使用できます。C-q

stty quit undefSIGQUIT押すとターミナルドライバが信号を送信するのを防ぎますC-\。同様に、フォアグラウンドプロセスを終了せずにキーをバインドに使用できます。

eval "$(dircolors -b ~/.dircolors)"lsから設定を読み込むようにコマンドを要求します~/.dircolors。コマンドの出力に応じて色をカスタマイズできますls

zshこの3行が現在シェルですでに実行されている場合は、再割り当てされないように保護する必要があるようです。しかし、どのような条件を使うべきかわかりません。

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

zshまた、これらのエラーメッセージを対話型シェルで実行しても問題は発生しないため、これらのエラーメッセージをよりよく理解したいと思います。なぜこのキーバインディングでのみエラーが発生するのですか?

答え1

zleウィジェットではzshstdinを閉じているようです。私はzshこれらのウィジェットのコマンドがユーザー入力を直接妨げることを避けたいのですが、/ dev / nullからstdinをリダイレクトする方が賢明でしょう(この問題は、次のバージョンで修正される予定です。)。

標準入力(ファイル記述子0)が閉じられると、コマンドで開かれた最初のファイルが標準入力になります(ファイル記述子が最初の無料ファイルから割り当てられるため)。

ではdircolorsエラーが発生します。dircolorsあなたのものを開いて、~/.dircolorsそれが既に標準入力(fdが返すものなのでopen())であることを知らずに標準入力にしてみてください。したがって、dup2(0,0)(stdinを自分にコピーすること)失敗し、EBADFエラーを報告しますdircolors

stty標準入力で開いている端末の設定を指定します。ここではstdinが閉じているため、sttyエラーが返されます。

ここでは、標準入力を端末に復元するようにウィジェットを変更できます。

reread_zshrc () . ~/.zshrc < $TTY

しかし、ウィジェット内でtty設定を変更することはzle(あなたのコマンドが何であるかはわかりませんがstty)悪い考えであることに注意してください。zlettyは行編集用の特殊モードに設定されており、ユーザーが操作したくないためです。 (そして編集が終わると、通常のtty設定がとにかく復元されるため、変更は失われます)。

したがって、stdinを作成する必要があるかもしれませ/dev/nullんが(実際には端末で作業をしたくないので)sttyまだ文句を言うので(/dev/nullttyデバイスではないので)stderrを/ dev / nullにリダイレクトすることもできます。これらのエラーメッセージを隠すには(非表示にしてもみんな間違った情報):

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

関連情報