Grep 找到匹配後退出很慢?

Grep 找到匹配後退出很慢?

我正在嘗試編寫一個 bash 腳本來輪詢 btmon 以獲取設備連接。我有一個可行的解決方案,但它慢得離譜,而且問題似乎是 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

編輯:澄清一下,cec btmon-client 是一個藍牙監控工具,是Bluez 套件的一部分,而cec-client 是一個與libCEC 打包在一起的實用程序,用於通過HDMI-CEC 串行總線(除其他外)發出命令。

答案1

在:

cmd1 | cmd2

大多數 shell(Bourne shell、(t)csh、以及 yash 和某些版本的 AT&T ksh 在某些情況下是值得注意的例外)都會等待cmd1cmd2

在 中bash,你會注意到

sleep 1 | uname

一秒後返回。

在:

btmon | grep -m 1 '@ Device Disconnected'

grep一旦發現該模式出現一次就會退出,但bash仍會等待btmon

btmongrep返回後,下次寫入管道時通常會死於 SIGPIPE ,但如果它不再寫入任何內容,則它永遠不會收到該訊號。

您可以替換#! /bin/bash為,#! /bin/ksh93 -因為這是一個相容的 shell bash,並且只等待管道的最後一個組件。然後在

btmon | grep -m 1 '@ Device Disconnected'

grep返回後,btmon將在背景運行,並且 shell 將繼續執行腳本的其餘部分。

如果你想btmon在返回後立即殺死grep,POSIXly,你可以這樣做:

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

相關內容