コマンド実行中にキー入力を受け付けたくない!
2年前くらいに作ったバックアップツールに文句が付く。
このバックアップツール、dialogって言うコンソールでダイアログを出せるコマンドを使ってメニュー画面を実現してます。
例えばこんな感じ。
dialog --yesno "むー!" 10 50 if [ $? = 1 ];then exit 0 fi hoge # 時間のかかるコマンド dialog --yesno "むぐ?" 10 50 if [ $? = 1 ];then exit 0 fi
んで、問題は時間のかかるコマンドhogeの実行中にキーボードからの先行入力(正式名称が分からないのでそう呼ぶ)を受け付けちゃうと。
例えばEnterキーを押すと前回のダイアログがスクロールしちゃって画面が崩れるって訳です。
いやそれ対策ないんですよ。てかみんな黙って使ってますやん。などと取り敢えずは逃げるも、なんか悔しいから対策を考えることにした。
で、出来たのが以下のシェルスクリプト。
#! /bin/sh stty -echo $* # 時間のかかるコマンド result=$? while true;do read -t 1 if [ $? = 1 ];then break fi done stty echo exit $result
まず、stty -echoでエコーバックを行わないようにすることで、取り敢えず先行入力が画面に表示されることは無くなった。
でも実際には先行入力が溜まっている状態なので、それがそのまま次のコマンドに渡ってしまって誤動作の原因になってしまう。
そこで、readのループで先行入力のはけ口を作った。
readには-tでタイムアウトが設定できるので、先行入力をすべて処理してから1秒後にシェルスクリプトから抜ける動きになる。
本当はタイムアウトをもっと短くしたいけど、設定は秒単位なのでこれが限界。まぁ対象は時間がかかるコマンドだからキニシナイ!
後、Enterを押しっぱなしにしてるうちはループから抜けられなかったり、Enterを伴わない先行入力は処理できないとかアラもあるけれど、今回のケースでは十分かなと。
丁度バックアップツールの新機種対応作業をやってるから、入れさせてもらお。