デバイス接続用にbtmonをポーリングするbashスクリプトを作成しようとしています。うまくいく解決策がありますが、とんでもなく遅く、問題は一致するものを見つけた後にgrepが非常に遅く(〜25秒)終了するようです。grep
スピードを上げたり完全に使用したくない場合はどうすればよいですか?
#!/bin/bash
COUNTER=0
while :
do
until btmon | grep -m 1 '@ Device Connected'
do :
done
let COUNTER=COUNTER+1
echo on 0 | cec-client RPI -s -d 1
sleep 5
echo as | cec-client RPI -s -d 1
until btmon | grep -m 1 '@ Device Disconnected'
do :
done
let COUNTER=COUNTER-1
if [ $COUNTER -eq 0 ];
then echo standby 0 | cec-client RPI -s -d 1;
fi
done
編集:明確にするために、btmon
cec-clientはBluezファミリーの一部であるBluetoothモニタリングツールであり、cec-clientはHDMI-CECシリアルバスを介して送信するためのlibCECと共にパッケージ化されたユーティリティです。
答え1
存在する:
cmd1 | cmd2
ほとんどのシェル(Bourneシェル、(t)csh、yash、および一部のAT&T kshバージョンは場合によっては注目に値する例外です)とcmd1
待機しますcmd2
。
ではbash
わかります。
sleep 1 | uname
1秒後に返されます。
存在する:
btmon | grep -m 1 '@ Device Disconnected'
grep
パターンが一度発生すると終了しますが、それbash
でも待ちますbtmon
。
btmon
grep
戻り後、通常は次にパイプに書き込むとSIGPIPEによって終了しますが、もはや何も書き込めない場合はその信号を受信しません。
互換性のあるシェルなので、置き換えることができ、#! /bin/bash
パイプの最後のコンポーネントだけを待ちます。それから#! /bin/ksh93 -
bash
btmon | grep -m 1 '@ Device Disconnected'
grep
返された後はbtmon
バックグラウンドで実行され、シェルは残りのスクリプトを実行し続けます。
btmon
POSIXly を返した直後に終了するには、grep
次のようにします。
sh -c 'echo "$$"; exec btmon' | (
read pid
grep -m1 '@ Device Disconnected' || exit
kill "$pid" 2> /dev/null
true)