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 comandigrep -m 1esce quando viene trovata una stringawatch -erestituisce 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:
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.{ ... ;}- 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)|- reindirizza lo stdout del lato sinistro allo stdin del lato destrogrep -m1 "find_me"- trova la stringa di destinazione&& kill -9 $(cat pid)- force kill (SIGKILL) iltailprocesso dopogrepesce una volta trovata la stringa corrispondente&& rm pid- rimuovi il file che abbiamo creato