端末がアクティブなウィンドウでないときに実行中のスクリプトを停止するためにキーボードショートカットを使用する最良の方法を見つけようとしています。
これにより、キーボードイベントを観察する方法のアイデアを得ることができますcat /dev/input/eventX
(ここで、Xはキーストロークイベントに対応する数字です)。
evtest
その後、イベント(キーストローク)が人間が読める形式で印刷されるまで実行されるツールについて学びました。
これまで私が管理してきたスクリプトですが、期待どおりに動作しません。完璧なソリューションでは、ユーザーはいつでもKey_Spaceを押してスクリプトを停止できますが、ここでは不可能だと思います。だから私の解決策はループの始めに2秒のウィンドウを提供することでした。
#!/bin/bash
exitCase='*type 1 (EV_KEY), code 57 (KEY_SPACE)*'
while [ true ] do
evtest /dev/input/eventX | read -s -t 2 line
if [ "$line" = "$exitCase" ]
then
echo caught event
exit 0
else
echo loop doing stuff
fi
done
問題は、スクリプトが繰り返しなしで一度実行されることです。これを行うより良い方法はありますか?それとも、終了状況に一致する入力が表示されるまでスクリプトを繰り返すようにどのように調整できますか?
もう1つの潜在的な問題は、1つのキーストロークが複数行を印刷することです。したがって、1つが必要な場合がありますevtest /dev/input/eventX | while read line
。ただし、試した後は、イベントを待っている間ではなく、イベントでのみ繰り返すことができます。
答え1
パイプの右側はevtest | read line
別のサブシェルで実行されるので(したがってline
便利な項目を設定しないため)、テストでいいえtrue で、スクリプトは無期限に実行されます。表示されていないスクリプトにコードがある可能性がありますか?
read
とにかくから始める必要はありませんevtest
。代わりに、以下を使用できますgrep
(これにより、最後に述べた「潜在的な問題」も解決されます)。
#!/bin/sh
exitCase='*type 1 (EV_KEY), code 57 (KEY_SPACE)*'
while true; do
if evtest /dev/input/eventX | grep -q -Fx -e "$exitCase"; then
echo caught event
break
else
echo loop doing stuff
fi
done
evtest
まったく同じ行が作成されると、ループは中断されます$exitCase
。静かにするように-q
指示するオプション(終了状態にのみ興味がある)では、文字列を次のように組み合わせる必要があります。grep
-F
grep
$exitCase
ひも正規表現ではなく-x
行全体を一致させる必要があります(文字列が先頭と末尾に固定されているかのように部分文字列なし)。
grep
タイムアウトを適用するには、GNU coreutilsをevtest
使用できますtimeout
。