単純な定形作業をLinuxとシェルスクリプトでやっつけることは多い。それを、パソコンの操作に習熟していない人に操作させることも多い。
処理スタート時にEnter入力で開始して、処理後は入力待ちで一旦停止し、再度Enter入力で処理を再開するような自動処理の無限ループスクリプトを書いた。入力を受け取るのには普通にreadコマンドを使った。
が、パートのおばちゃんが操作するので予期しない事態が起きる。用意したデバイスもあまりよくないものだったので、キーのチャタリングや押し間違いなどで、余計にEnterが入力されてしまう。すると、処理中に入力バッファにたまったキー入力が、処理後にreadコマンドに受け取られてしまい、開始前に一時停止せずに予期せず処理が先に進んでしまう。これはマズい。
しょうがないので、次のループに行く前に、バッファが続く限りreadコマンドを発行する別のループ処理を用意してキーバッファを消去した。
ただ、それだけだとバッファ消去処理のread待ちで止まってしまい、期待した動作にならない。
止まってしまうのを回避するために、バッファ消去処理のreadにはタイムアウトを設定してbreakするようにした。
readコマンドの-tオプションのタイムアウトは、bash環境では1以下の値を設定できないようなので1秒も待たせることになってしまった。
readはEnterの入力を待つので、操作として有効なキー入力はEnterがある時に限定される。それ以外のゴミ入力が入っても、動作のトリガーはreadができた(=Enter入力があった)ことしか確認していないので、問題がない。
これで、パートのおばちゃんの操作でも問題が出なくなった。
#!/bin/bash
while true
do
echo "start: "
read input
echo "REL: $input"
sleep 2 # ここで何かの処理をする
while read -t 1 line
do
echo "trash loop: $line"
done
done
後日追記:この記事を書いたのは、確かRaspiで出荷検査時にファームアップデートと確認するような治具を作ったときだったような。
オリジナル投稿: シェルスクリプトで入力待ち無限ループ処理時のキーバッファ消去|kinneko|pixivFANBOX
https://www.fanbox.cc/@kinneko/posts/665481


