J'essaie d'écrire un script bash qui interroge btmon pour les connexions de périphériques. J'ai une solution de travail, mais c'est absurdement lent, et il semble que le problème est que grep est très lent à sortir après avoir trouvé une correspondance (environ 25 secondes). Que puis-je faire pour accélérer grep
ou éviter de l'utiliser ?
#!/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 :pour clarifier, btmon
et est un outil de surveillance Bluetooth qui fait partie de la suite Bluez, et cec-client est un utilitaire fourni avec libCEC pour émettre des commandes sur le bus série HDMI-CEC (entre autres).
Réponse acceptée :
Dans :
cmd1 | cmd2
La plupart des shells (le shell Bourne, (t)csh, ainsi que yash et certaines versions d'AT&T ksh sous certaines conditions étant les exceptions notables) attendent à la fois cmd1
et cmd2
.
Dans bash
, vous remarquerez que
sleep 1 | uname
revient après une seconde.
Dans :
btmon | grep -m 1 '@ Device Disconnected'
grep
sortira dès qu'il aura trouvé une occurrence du motif, mais bash
attendra toujours btmon
.
btmon
mourra généralement d'un SIGPIPE la prochaine fois qu'il écrira dans le tube après grep
est revenu, mais s'il n'écrit plus jamais rien, il ne recevra jamais ce signal.
Vous pouvez remplacer #! /bin/bash
avec #! /bin/ksh93
car c'est un shell compatible avec bash
et un qui n'attend que le dernier composant d'un pipeline. Puis dans
btmon | grep -m 1 '@ Device Disconnected'
après grep
renvoie, btmon
serait laissé en arrière-plan et le shell continuerait avec le reste du script.
Si vous vouliez tuer btmon
dès que grep
renvoie, POSIXly, vous pouvez faire quelque chose comme :
sh -c 'echo "$$"; exec btmon' | (
read pid
grep -m1 '@ Device Disconnected' || exit
kill "$pid" 2> /dev/null
true)