特定のキーを押すまでbashシェルスクリプトでループを実行しています(Ctrl-Cは常に私に残酷です)。 -s オプションを使用しましたが、read
端末には単一文字が表示されます。 -sオプションがread
期待どおりに機能しないのはなぜですか?
until read -s -n 1 -t 0.01; do
echo -n "."
sleep .5 # actual script code goes here
done
echo
答え1
sleep .5
私はこれが実行中ではなく、実行中にキーを押したためだと確信していますread
。
詳しくは、実行中にread -s -n 1 -t 0.01
端末を0.01秒間noechoモードに切り替えてからタイムアウトし、エコーが再びオンになります。その0.01秒以内に文字を入力すると、その文字は反転しませんが、そのウィンドウを見逃す可能性があります。代わりにsleep .5
実行時に入力すると、再びエコーされます。その後、0.5秒後にもう一度実行し、read
エコーをオフにして(遅すぎます!)、事前入力バッファから文字を読み取り、最後にエコーを再びオンにします。
(注:このecho
コマンドとechoターミナルモードは両方ともターミナルへの印刷に関連していることを除いて、直接的な関係はありません。)
read -s
回避策:エコーをオフにすることを期待しないで、stty -echo
最初に一度使用してstty echo
最後にもう一度オンにします。 Billyの叔父がコメントで指摘したように、trap
何らかの理由でControl-Cなどのスクリプトが異常終了した場合は、端末設定が正常に戻るようにaを追加することも賢明です。
trap 'stty echo' EXIT # If script exits abnormally, fix terminal
stty -echo # turn off echo
until read -n 1 -t 0.01; do
echo -n "."
sleep .5
done
echo
stty echo # turn echo back on
(trap
後で削除できますが問題ありません。端末を元に戻すのはとにかく安全です。)
sleep
編集:ilkkachuがコメントで指摘したように、完全に削除してより長いタイムアウトを使用することをお勧めしますread
。これにより、キーを押したときにキーを押すのに気づくまで0.5秒待ちません。より長いタイムアウトを使用することもできます。毎回個別にエコーをオフにするstty -echo
代わりに、エコーをオフにする方法を使い続けます。read -s
trap 'stty echo' EXIT
stty -echo # turn off echo
until read -n 1 -t 3600; do # 1 hour timeout, 'cause why not
echo -n "."
done
echo
stty echo # turn echo back on
ループが不要な場合は完全に削除できます(この場合はread -s
正しく機能します)。
read -s -n 1