Estoy tratando de escribir un script bash que sondee btmon para conexiones de dispositivos. Tengo una solución que funciona, pero es absurdamente lenta, y parece que el problema es que grep tarda mucho en salir después de encontrar una coincidencia (alrededor de 25 segundos). ¿Qué puedo hacer para acelerar grep o evitar usarlo por completo?
#!/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
 editar:para aclarar, btmon y es una herramienta de monitoreo de bluetooth que forma parte de la suite Bluez, y cec-client es una utilidad que se incluye con libCEC para emitir comandos a través del bus serie HDMI-CEC (entre otras cosas).
Respuesta aceptada:
en:
cmd1 | cmd2
 La mayoría de los shells (el Bourne shell, (t)csh, así como yash y algunas versiones de AT&T ksh en algunas condiciones son las excepciones notables) esperan tanto cmd1 y cmd2 .
 En bash , notarás que
sleep 1 | uname
regresa después de un segundo.
en:
btmon | grep -m 1 '@ Device Disconnected'
 grep saldrá tan pronto como haya encontrado una ocurrencia del patrón, pero bash seguirá esperando btmon .
 btmon normalmente morirá de un SIGPIPE la próxima vez que escriba en la tubería después de grep ha regresado, pero si nunca vuelve a escribir nada, nunca recibiría esa señal.
 ¡Podrías reemplazar #! /bin/bash con #! /bin/ksh93 ya que es un shell compatible con bash y uno que solo espera el último componente de una canalización. Luego en
btmon | grep -m 1 '@ Device Disconnected'
 después de grep devuelve, btmon se dejaría ejecutándose en segundo plano y el shell continuaría con el resto del script.
 Si quisieras matar a btmon tan pronto como grep regresa, POSIXly, podría hacer algo como:
sh -c 'echo "$$"; exec btmon' | (
   read pid
   grep -m1 '@ Device Disconnected' || exit
   kill "$pid" 2> /dev/null
   true)