Použijte smyčku:
until my_cmd | grep -m 1 "String Im Looking For"; do : ; done
Místo :
, můžete použít sleep 1
(nebo 0.2) pro usnadnění CPU.
Cyklus běží, dokud grep nenajde řetězec ve výstupu příkazu. -m 1
znamená "jedna shoda stačí", tj. grep přestane hledat, jakmile najde první shodu.
Můžete také použít grep -q
který se také ukončí po nalezení první shody, ale bez vytištění shodného řádku.
watch -e "! my_cmd | grep -m 1 \"String Im Looking For\""
!
neguje výstupní kód příkazového kanálugrep -m 1
ukončí se, když je nalezen řetězecwatch -e
vrátí, pokud dojde k nějaké chybě
To však lze vylepšit tak, aby se skutečně zobrazila ta shodná čára, která je zatím zahozena.
Pro ty, kteří mají program, který nepřetržitě zapisuje do stdout, vše, co musíte udělat, je použít potrubí grep s možností 'single match'. Jakmile grep najde odpovídající řetězec, ukončí se, čímž se ukončí stdout procesu, který je směrován do grep. Tato událost by měla přirozeně způsobí, že se program elegantně ukončí pokud proces znovu zapisuje .
Stane se, že proces obdrží SIGPIPE, když se pokusí zapsat do uzavřeného stdout po ukončení grep. Zde je příklad s pingem, který by jinak běžel neomezeně dlouho:
$ ping superuser.com | grep -m 1 "icmp_seq"
Tento příkaz se shoduje s prvním úspěšným 'pongem' a poté se ukončí při příštím ping
pokusí se zapisovat do stdout.
Nicméně
Není vždy zaručeno, že proces znovu zapíše do stdout, a proto nemusí způsobit vyvolání SIGPIPE (např. k tomu může dojít při sledování souboru protokolu). Nejlepší řešení, které se mi pro tento scénář podařilo vymyslet, zahrnuje zápis do souboru; prosím komentujte, pokud si myslíte, že byste se mohli zlepšit:
$ { tail -f log_file & echo $! > pid; } | { grep -m1 "find_me" && kill -9 $(cat pid) && rm pid; }
Rozebrat toto:
tail -f log_file & echo $! > pid
- otočí soubor, připojí proces k pozadí a uloží PID ($!
) do souboru. Zkoušel jsem místo toho exportovat PID do proměnné, ale zdá se, že mezi zde a opětovným použitím PID existuje spor.{ ... ;}
- seskupte tyto příkazy dohromady, abychom mohli výstup převést do grep při zachování aktuálního kontextu (pomáhá při ukládání a opětovném použití proměnných, ale nepodařilo se mi zprovoznit tuto část)|
- stdout levé strany k stdin pravé stranygrep -m1 "find_me"
- najít cílový řetězec&& kill -9 $(cat pid)
- vynutit zabití (SIGKILL)tail
proces pogrep
ukončí se, jakmile najde odpovídající řetězec&& rm pid
- odstranit soubor, který jsme vytvořili