Я пытаюсь написать 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
редактировать: чтобы уточнить, btmon
это инструмент мониторинга bluetooth, входящий в комплект Bluez, а cec-client - это утилита, которая поставляется вместе с libCEC для выдачи команд через последовательную шину HDMI-CEC (среди прочего).
btmon
выводит? Вы уверены, что это не просто вопрос буферизации?btmon
реализует саму буферизацию, и в этом случае вам не повезло.Ответы:
В:
Большинство оболочек (оболочка Bourne, (t) csh, а также yash и некоторые версии AT & T ksh при некоторых условиях, являющихся заметными исключениями) ждут обоих
cmd1
иcmd2
.В
bash
, вы заметите, чтовозвращается через одну секунду.
В:
grep
выйдет, как только он обнаружит одно вхождение шаблона, ноbash
все равно будет ждатьbtmon
.btmon
обычно умирает от SIGPIPE при следующей записи в канал послеgrep
возвращения, но если он никогда ничего не записывает, он никогда не получит этот сигнал.Вы могли бы заменить
#! /bin/bash
с ,#! /bin/ksh93
как это оболочка совместима сbash
и один , который ждет только для последнего компонента трубопровода. Затем впосле
grep
возвратаbtmon
будет работать в фоновом режиме, и оболочка будет продолжать работу с остальной частью сценария.Если вы хотите убить,
btmon
как толькоgrep
вернетесь, POSIXly, вы можете сделать что-то вроде:источник