バージョン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 undef
SIGQUIT
押すとターミナルドライバが信号を送信するのを防ぎます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
ウィジェットではzsh
stdinを閉じているようです。私は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
)悪い考えであることに注意してください。zle
ttyは行編集用の特殊モードに設定されており、ユーザーが操作したくないためです。 (そして編集が終わると、通常のtty設定がとにかく復元されるため、変更は失われます)。
したがって、stdinを作成する必要があるかもしれませ/dev/null
んが(実際には端末で作業をしたくないので)stty
まだ文句を言うので(/dev/null
ttyデバイスではないので)stderrを/ dev / nullにリダイレクトすることもできます。これらのエラーメッセージを隠すには(非表示にしてもみんな間違った情報):
reread_zshrc() . ~/.zshrc < /dev/null 2> /dev/null