一致が見つかった後、Grep の終了が遅いですか?

一致が見つかった後、Grep の終了が遅いですか?

デバイス接続のために 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'

が戻った後はgrepbtmonバックグラウンドで実行されたままになり、シェルはスクリプトの残りの部分を続行します。

btmonPOSIX では、返されたらすぐに強制終了したい場合は、grep次のようにします。

sh -c 'echo "$$"; exec btmon' | (
   read pid
   grep -m1 '@ Device Disconnected' || exit
   kill "$pid" 2> /dev/null
   true)

関連情報