GNU/Linux >> Linux Esercitazione >  >> Linux

Grep lento per uscire dopo aver trovato la corrispondenza?

Sto cercando di scrivere uno script bash che esegua il polling di btmon per le connessioni dei dispositivi. Ho una soluzione funzionante, ma è assurdamente lenta e sembra che il problema sia che grep è molto lento a uscire dopo aver trovato una corrispondenza (circa 25 secondi). Cosa posso fare per velocizzare grep up o evitare di usarlo del tutto?

#!/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

modifica:per chiarire, btmon ed è uno strumento di monitoraggio Bluetooth che fa parte della suite Bluez, e cec-client è un'utilità inclusa in libCEC per l'emissione di comandi attraverso il bus seriale HDMI-CEC (tra le altre cose).

Risposta accettata:

In:

cmd1 | cmd2

La maggior parte delle shell (la Bourne shell, (t)csh, così come yash e alcune versioni di AT&T ksh in alcune condizioni essendo le eccezioni notevoli) aspettano entrambi cmd1 e cmd2 .

In bash , lo noterai

sleep 1 | uname

ritorna dopo un secondo.

In:

btmon | grep -m 1 '@ Device Disconnected'

grep uscirà non appena avrà trovato un'occorrenza del pattern, ma bash attenderà ancora btmon .

btmon in genere morirà di un SIGPIPE la prossima volta che scriverà nella pipe dopo grep è tornato, ma se non scrive più nulla, non riceverà mai quel segnale.

Potresti sostituire #! /bin/bash con #! /bin/ksh93 dato che è una shell compatibile con bash e uno che attende solo l'ultimo componente di una pipeline. Poi in

btmon | grep -m 1 '@ Device Disconnected'

dopo grep restituisce, btmon verrebbe lasciato in esecuzione in background e la shell continuerebbe con il resto dello script.

Se volevi uccidere btmon non appena grep restituisce, POSIXly, potresti fare qualcosa del tipo:

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

Linux
  1. Corrispondenza di pattern multilinea utilizzando Sed, Awk o Grep?

  2. Come fermare il comando Trova dopo la prima partita?

  3. Stampa la riga precedente dopo una corrispondenza di pattern utilizzando Sed?

  4. Trovare l'ultimo elemento di una riga usando Grep?

  5. Come contare il numero di righe in un file dopo una corrispondenza Grep?

Come eseguire Grep con multipli e pattern?

Mantieni la colorazione dopo aver applicato le tubazioni da grep a grep

Abbina due stringhe in una riga con grep

Perché uscire dal codice 141 con grep -q?

Come conservare il container alpino docker dopo l'uscita?

Espressione regolare per trovare caratteri doppi in Bash