読み取りの無音オプションは無視されますか?

読み取りの無音オプションは無視されますか?

特定のキーを押すまで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

関連情報