GNU/Linux >> Tutoriales Linux >  >> Linux

¿Grep lento para salir después de encontrar una coincidencia?

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)

Linux
  1. ¿Cómo ejecutar Grep con patrones múltiples y?

  2. ¿Coincidencia de patrones multilínea usando Sed, Awk o Grep?

  3. ¿Cómo detener el comando Buscar después de la primera coincidencia?

  4. ¿Encontrar el último elemento en una línea usando Grep?

  5. Encontrar el recuento de procesos en Linux a través de la línea de comandos

¿Imprimir línea anterior después de una coincidencia de patrón usando Sed?

¿Cómo contar el número de líneas en un archivo después de una coincidencia Grep?

Conservar la coloración después de canalizar grep a grep

Une dos cadenas en una línea con grep

Linux sudo funciona lento después de cambiar el nombre de host

Expresión regular para encontrar caracteres dobles en Bash