Verwenden Sie eine Schleife:
until my_cmd | grep -m 1 "String Im Looking For"; do : ; done
Statt :
, können Sie sleep 1
verwenden (oder 0.2), um die CPU zu entlasten.
Die Schleife wird ausgeführt, bis grep die Zeichenfolge in der Ausgabe des Befehls findet. -m 1
bedeutet "eine Übereinstimmung ist genug", d.h. grep stoppt die Suche, nachdem es die erste Übereinstimmung gefunden hat.
Sie können auch grep -q
verwenden die ebenfalls nach dem Finden der ersten Übereinstimmung beendet wird, aber ohne die übereinstimmende Zeile zu drucken.
watch -e "! my_cmd | grep -m 1 \"String Im Looking For\""
!
negiert den Exitcode der Befehlspipelinegrep -m 1
wird beendet, wenn eine Zeichenfolge gefunden wirdwatch -e
gibt zurück, wenn ein Fehler aufgetreten ist
Dies kann jedoch verbessert werden, um tatsächlich die übereinstimmende Zeile anzuzeigen, die bisher verworfen wurde.
Für diejenigen, die ein Programm haben, das ständig in stdout schreibt, müssen Sie es nur mit der Option "Single Match" an grep leiten. Sobald grep die passende Zeichenfolge gefunden hat, wird es beendet, wodurch stdout für den Prozess geschlossen wird, der an grep geleitet wird. Dieses Ereignis sollte bewirken natürlich, dass das Programm ordnungsgemäß beendet wird, solange der Prozess erneut schreibt .
Was passieren wird, ist, dass der Prozess ein SIGPIPE erhält, wenn er versucht, in die geschlossene Standardausgabe zu schreiben, nachdem grep beendet wurde. Hier ein Beispiel mit Ping, das sonst endlos laufen würde:
$ ping superuser.com | grep -m 1 "icmp_seq"
Dieser Befehl stimmt mit dem ersten erfolgreichen 'pong' überein und wird dann beim nächsten Mal beendet ping
versucht in stdout zu schreiben.
Allerdings
Es ist nicht immer garantiert, dass der Prozess erneut auf stdout schreibt und daher möglicherweise nicht dazu führt, dass ein SIGPIPE ausgelöst wird (z. B. kann dies beim Tailing einer Protokolldatei passieren). Die beste Lösung, die ich für dieses Szenario gefunden habe, besteht darin, in eine Datei zu schreiben. Bitte kommentieren Sie, wenn Sie glauben, dass Sie sich verbessern können:
$ { tail -f log_file & echo $! > pid; } | { grep -m1 "find_me" && kill -9 $(cat pid) && rm pid; }
Aufschlüsselung:
tail -f log_file & echo $! > pid
- Tails einer Datei, hängt den Prozess an den Hintergrund an und speichert die PID ($!
) in eine Datei. Ich habe versucht, die PID stattdessen in eine Variable zu exportieren, aber es scheint, dass es zwischen hier und der erneuten Verwendung der PID eine Race-Condition gibt.{ ... ;}
- gruppieren Sie diese Befehle, damit wir die Ausgabe an grep weiterleiten können, während der aktuelle Kontext beibehalten wird (hilft beim Speichern und Wiederverwenden von Variablen, konnte diesen Teil jedoch nicht zum Laufen bringen)|
- stdout der linken Seite an stdin der rechten Seite leitengrep -m1 "find_me"
- Finden Sie die Zielzeichenfolge&& kill -9 $(cat pid)
- Erzwinge das Beenden (SIGKILL) vontail
Prozess nachgrep
wird beendet, sobald es die passende Zeichenfolge gefunden hat&& rm pid
- Entfernen Sie die von uns erstellte Datei