デバイス接続のために btmon をポーリングする bash スクリプトを作成しようとしています。 実用的な解決策はありますが、非常に遅く、一致が見つかった後の grep の終了が非常に遅い (約 25 秒) ことが問題のようです。 速度をgrep
上げるか、または 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
は 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
パターンが 1 つ見つかるとすぐに終了しますが、bash
を待機し続けますbtmon
。
btmon
通常、が戻った後にパイプに書き込むときに SIGPIPE で終了しますgrep
が、再度何も書き込まない場合は、そのシグナルを受信することはありません。
#! /bin/bash
を に置き換えることができます。#! /bin/ksh93 -
これは と互換性がありbash
、パイプラインの最後のコンポーネントのみを待つシェルです。
btmon | grep -m 1 '@ Device Disconnected'
が戻った後はgrep
、btmon
バックグラウンドで実行されたままになり、シェルはスクリプトの残りの部分を続行します。
btmon
POSIX では、返されたらすぐに強制終了したい場合は、grep
次のようにします。
sh -c 'echo "$$"; exec btmon' | (
read pid
grep -m1 '@ Device Disconnected' || exit
kill "$pid" 2> /dev/null
true)