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)