Ich versuche, ein Bash-Skript zu schreiben, das Btmon nach Geräteverbindungen abfragt. Ich habe eine funktionierende Lösung, aber sie ist absurd langsam, und es scheint, als ob das Problem darin besteht, dass grep sehr langsam beendet wird, nachdem eine Übereinstimmung gefunden wurde (etwa 25 Sekunden). Was kann ich tun, um entweder grep zu beschleunigen oder ganz darauf verzichten?
#!/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
Bearbeiten:Zur Verdeutlichung btmon und ist ein Bluetooth-Überwachungstool, das Teil der Bluez-Suite ist, und cec-client ist ein Dienstprogramm, das mit libCEC geliefert wird, um (unter anderem) Befehle über den seriellen HDMI-CEC-Bus auszugeben.
Akzeptierte Antwort:
In:
cmd1 | cmd2
Die meisten Shells (die Bourne-Shell, (t)csh sowie yash und einige Versionen von AT&T ksh unter bestimmten Bedingungen, die die bemerkenswerten Ausnahmen darstellen) warten sowohl auf cmd1 und cmd2 .
In bash , das wirst du merken
sleep 1 | uname
kehrt nach einer Sekunde zurück.
In:
btmon | grep -m 1 '@ Device Disconnected'
grep wird beendet, sobald es ein Vorkommen des Musters gefunden hat, aber bash wird immer noch auf btmon warten .
btmon stirbt normalerweise an einer SIGPIPE, wenn es das nächste Mal nach grep in die Pipe schreibt zurückgekehrt ist, aber wenn es nie wieder etwas schreibt, würde es dieses Signal nie erhalten.
Sie könnten #! /bin/bash mit #! /bin/ksh93 da dies eine Shell ist, die mit bash kompatibel ist und eine, die nur auf die letzte Komponente einer Pipeline wartet. Dann in
btmon | grep -m 1 '@ Device Disconnected'
nach grep gibt zurück, btmon würde im Hintergrund laufen und die Shell würde mit dem Rest des Skripts fortfahren.
Wenn Sie btmon töten wollten sobald grep zurückgibt, POSIXly, könnten Sie so etwas tun:
sh -c 'echo "$$"; exec btmon' | (
read pid
grep -m1 '@ Device Disconnected' || exit
kill "$pid" 2> /dev/null
true)