一致するものを見つけた後、Grepはゆっくり終了しますか?

一致するものを見つけた後、Grepはゆっくり終了しますか?

デバイス接続用に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

編集:明確にするために、btmoncec-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

btmongrep戻り後、通常は次にパイプに書き込むとSIGPIPEによって終了しますが、もはや何も書き込めない場合はその信号を受信しません。

互換性のあるシェルなので、置き換えることができ、#! /bin/bashパイプの最後のコンポーネントだけを待ちます。それから#! /bin/ksh93 -bash

btmon | grep -m 1 '@ Device Disconnected'

grep返された後はbtmonバックグラウンドで実行され、シェルは残りのスクリプトを実行し続けます。

btmonPOSIXly を返した直後に終了するには、grep次のようにします。

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

関連情報