¿Grep tarda en salir después de encontrar una coincidencia?

¿Grep tarda en salir después de encontrar una coincidencia?

Estoy intentando escribir un script bash que sondee btmon para detectar 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 acelerarlo grepo evitar su uso 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, btmones una herramienta de monitoreo de bluetooth que forma parte de la suite Bluez, y cec-client es una utilidad incluida con libCEC para emitir comandos a través del bus serie HDMI-CEC (entre otras cosas).

Respuesta1

En:

cmd1 | cmd2

La mayoría de los shells (el shell Bourne, (t)csh, así como yash y algunas versiones de AT&T ksh bajo algunas condiciones son excepciones notables) esperan tanto cmd1y cmd2.

En bash, notarás que

sleep 1 | uname

regresa después de un segundo.

En:

btmon | grep -m 1 '@ Device Disconnected'

grepSaldrá tan pronto como encuentre una aparición del patrón, pero bashaún esperará btmon.

btmonPor lo general, un SIGPIPE morirá la próxima vez que escriba en la tubería después de grephaber regresado, pero si nunca vuelve a escribir nada, nunca recibirá esa señal.

Puede reemplazarlo #! /bin/bashcon, #! /bin/ksh93 -ya que es un shell compatible bashy que solo espera el último componente de una canalización. Luego en

btmon | grep -m 1 '@ Device Disconnected'

después de grepregresar, btmonse dejaría ejecutándose en segundo plano y el shell continuaría con el resto del script.

Si quisieras matar btmontan pronto como grepregrese, POSIXly, podrías hacer algo como:

sh -c 'echo "$$"; exec btmon' | (
   read pid
   grep -m1 '@ Device Disconnected' || exit
   kill "$pid" 2> /dev/null
   true)

información relacionada