zshで読み取るために-uと-kを使用すると問題が発生する

zshで読み取るために-uと-kを使用すると問題が発生する

read -kを使用するzshスクリプトを開発しています。このようなスクリプトを実行すると(echo a | myscript)入力が受けられません。明らかに、これは-kが常に/ dev / ttyを標準入力として使用するため、readなどの標準入力を使用するように指示する必要がありますread -u0

ただし、これを-u0(以前のケースが機能するようにする)に変更してttyをリダイレクトせずにスクリプトを実行すると、スクリプトが中断され、-u0なしで行ったようにまったく実行されません。同じです。

編集する:デバッグ後の問題は単純なようです。 -u0 を使用した後、-k1 オプションはもはや単一文字を読み取らずに停止します。この場合、読み取りはすべての入力をバッファリングし、EOLが到着するとすぐに保存することを除いて、-kなしで同じように機能します。

編集2:もう少しデバッグした後、これは-u0とは機能しない生モードに関連していることがわかりました。読み込み前にstty raw / cookedを追加すると機能しますが、入力キーストロークを処理するために\ nの代わりに\ rを使用する場合を除き、tty以外のstdinを使用して実行すると操作が中断されます。

両方のモードを互換性にする方法はありますか?

実際、スクリプトが完全に異なる動作をする理由を理解したいと思います。 fd0 は、-u0 を使用して読み込んだり読み込んだりしない場合でも、デフォルトでは /dev/tty と同じです。

答え1

read -k2つの動作モードがあります:(N文字を読む)とread -q(読み取りyまたは):n

  • デフォルトでは端末から読み込みます。それらは1行ずつ読み込むのではなく、バイト単位で読み込む(必要なだけ読み取る)ために端末を生モードに設定します。
  • 既存のファイル記述子(-u数値または-p現在のコプロセスと通信するために使用されるパイプ)から読み取るように指示できます。この場合、ファイル記述子から読み取るだけです。

zshに特定のソースから読み込むように指示するオプションはありませんが、端末から読み込む場合は、端末モードを変更してください。ただし、自分で設定できます。標準入力が端末であることを確認し、-u0端末の場合は渡さないでください。

if [[ -t 0 ]]; then
  read -k1 …
else
  read -k1 -u0 …
fi

関連情報