GNU/Linux >> Linux Esercitazione >  >> Linux

guarda l'output di un comando finché non viene osservata una stringa particolare e poi esci

Usa un ciclo:

until my_cmd | grep -m 1 "String Im Looking For"; do : ; done

Invece di : , puoi usare sleep 1 (o 0.2) per alleggerire la CPU.

Il ciclo viene eseguito finché grep non trova la stringa nell'output del comando. -m 1 significa "una corrispondenza è sufficiente", ovvero grep interrompe la ricerca dopo aver trovato la prima corrispondenza.

Puoi anche usare grep -q che si chiude anche dopo aver trovato la prima corrispondenza, ma senza stampare la riga corrispondente.


watch -e "! my_cmd | grep -m 1 \"String Im Looking For\""
  • ! nega il codice di uscita della pipeline dei comandi
  • grep -m 1 esce quando viene trovata una stringa
  • watch -e restituisce se si è verificato un errore

Ma questo può essere migliorato per visualizzare effettivamente quella linea abbinata, che finora è stata buttata via.


Per coloro che hanno un programma che scrive continuamente su stdout, tutto ciò che devi fare è reindirizzarlo a grep con l'opzione 'single match'. Una volta che grep trova la stringa corrispondente, uscirà, chiudendo lo stdout sul processo che viene reindirizzato a grep. Questo evento dovrebbe naturalmente fa sì che il programma esca normalmente fintanto che il processo scrive di nuovo .

Quello che accadrà è che il processo riceverà un SIGPIPE quando proverà a scrivere su stdout chiuso dopo che grep è uscito. Ecco un esempio con ping, che altrimenti verrebbe eseguito all'infinito:

$ ping superuser.com | grep -m 1 "icmp_seq"

Questo comando corrisponderà al primo 'pong' riuscito, quindi uscirà la volta successiva ping prova a scrivere su stdout.

Tuttavia,

Non è sempre garantito che il processo scriva di nuovo su stdout e quindi potrebbe non causare l'innalzamento di un SIGPIPE (ad esempio, ciò può accadere durante il tailing di un file di registro). La migliore soluzione che sono riuscito a trovare per questo scenario prevede la scrittura su un file; per favore commenta se pensi di poter migliorare:

$ { tail -f log_file & echo $! > pid; } | { grep -m1 "find_me" && kill -9 $(cat pid) && rm pid; }

Analizzando questo:

  1. tail -f log_file & echo $! > pid - accoda un file, allega il processo in background e salva il PID ($! ) in un file. Ho provato invece a esportare il PID in una variabile, ma sembra che ci sia una condizione di competizione tra qui e quando il PID viene riutilizzato.
  2. { ... ;} - raggruppare questi comandi in modo da poter reindirizzare l'output a grep mantenendo il contesto corrente (aiuta quando si salvano e si riutilizzano le variabili, ma non è stato possibile far funzionare quella parte)
  3. | - reindirizza lo stdout del lato sinistro allo stdin del lato destro
  4. grep -m1 "find_me" - trova la stringa di destinazione
  5. && kill -9 $(cat pid) - force kill (SIGKILL) il tail processo dopo grep esce una volta trovata la stringa corrispondente
  6. && rm pid - rimuovi il file che abbiamo creato

Linux
  1. CentOS / RHEL:come ottenere la data e l'ora del comando eseguito nell'output del comando della cronologia

  2. Converti un output in una stringa

  3. Come posso eseguire il loop sull'output di un comando di shell?

  4. Memorizza l'output del comando date e watch in un file

  5. Ciclo ricorsivo delle directory ed esecuzione di un comando su un file nella directory

Controlla i comandi e le attività con il comando watch di Linux

Comando di uscita Bash e codici di uscita

Prettyping – Rendi l'output del comando Ping più carino e più facile da leggere

Utilizzare Command Grep e individuare?

Uso del comando grep in Linux

Smetti di guardare l'output di un particolare programma dopo aver usato il comando watch?