次のコードがコマンドを完了できないのはなぜですかfoo
?次のように入力すると、シェルがフリーズfoo <Tab>
して押すまで^C
(exitコマンドが完了します)、入力は許可されません。
私の仮定は、/dev/tty
シェルがそれを読み、それがcat
それを読む能力に何とか影響を与えるということです。ただし、この場合はまだ解決策が必要です。
_foo() {
_values 'foo' "$(cat < /dev/tty)"
}
compdef _foo foo
この例は意図的に単純化されています。実際のユースケースは、非ターミナルインタフェースプログラム(ncursesを考えてみてください)を実行することですcat
。
ベストアンサー1
完了時にzsh行エディタにあるので、次のようにターミナル行ルールの独自の行エディタが無効になります。
stty -icanon -echo
このモードでは、入力の終わり(行ルールの行エディタの動作の一部)を通知できず、入力した内容のエコーが表示されないため、cat
終了する方法はありません。^D
icanon
次のことができます。
_foo() {
_values 'foo' "$(
{
s=$(stty -g)
stty sane
cat
stty $s
} < /dev/tty)"
zle -I
}
つまり、実行前にターミナルデバイスを期待したままにしてcat
(^D
空白行を押すか、ダブルクリックして入力を終了できます)、cat
実行後に復元します。私たちは、zleに、ラインルールラインエディタに入力したコンテンツのエコーが原因で混乱するので、プロンプトとバッファを再描画する必要があると言いますzle -I
(無効)。