Snažím se napsat bash skript, který dotazuje btmon na připojení zařízení. Mám funkční řešení, ale je absurdně pomalé a zdá se, že problém je v tom, že grep se po nalezení shody velmi pomalu ukončuje (asi 25 sekund). Co mohu udělat pro zrychlení grep
nebo se ho úplně vyhnout?
#!/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
edit:Pro upřesnění, btmon
a je to nástroj pro monitorování bluetooth, který je součástí sady Bluez, a cec-client je nástroj, který je součástí sady libCEC pro vydávání příkazů přes sériovou sběrnici HDMI-CEC (mimo jiné).
Přijatá odpověď:
V:
cmd1 | cmd2
Většina shellů (Bourne shell, (t)csh, stejně jako yash a některé verze AT&T ksh za určitých podmínek, které jsou významnými výjimkami) čekají na oba cmd1
a cmd2
.
V bash
, všimnete si toho
sleep 1 | uname
vrátí se po jedné sekundě.
V:
btmon | grep -m 1 '@ Device Disconnected'
grep
ukončí se, jakmile nalezne jeden výskyt vzoru, ale bash
bude stále čekat na btmon
.
btmon
typicky zemře na SIGPIPE při příštím zápisu do roury po grep
se vrátil, ale pokud už nikdy nic nezapíše, nikdy by tento signál neobdržel.
Můžete nahradit #! /bin/bash
s bash
a ten, který čeká pouze na poslední komponent potrubí. Poté v
btmon | grep -m 1 '@ Device Disconnected'
za grep
vrátí, btmon
by zůstal spuštěný na pozadí a shell by pokračoval se zbytkem skriptu.
Pokud jste chtěli zabít btmon
jakmile grep
vrátí, POSIXly, můžete udělat něco jako:
sh -c 'echo "$$"; exec btmon' | (
read pid
grep -m1 '@ Device Disconnected' || exit
kill "$pid" 2> /dev/null
true)