完了関数から/dev/ttyを読む

完了関数から/dev/ttyを読む

次のコードがコマンドを完了できないのはなぜですか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終了する方法はありません。^Dicanon

次のことができます。

_foo() {
  _values 'foo' "$(
    {
      s=$(stty -g)
      stty sane
      cat
      stty $s
    } < /dev/tty)"
  zle -I
}

つまり、実行前にターミナルデバイスを期待したままにしてcat^D空白行を押すか、ダブルクリックして入力を終了できます)、cat実行後に復元します。私たちは、zleに、ラインルールラインエディタに入力したコンテンツのエコーが原因で混乱するので、プロンプトとバッファを再描画する必要があると言いますzle -I無効)。

おすすめ記事