ループを使用:
until my_cmd | grep -m 1 "String Im Looking For"; do : ; done
:
の代わりに 、 sleep 1
を使用できます (または 0.2) CPU を緩和します。
ループは、grep がコマンドの出力で文字列を見つけるまで実行されます。 -m 1
「1 つの一致で十分」という意味です。つまり、grep は最初の一致が見つかった後に検索を停止します。
grep -q
も使用できます これも最初の一致を見つけた後に終了しますが、一致する行は出力しません。
watch -e "! my_cmd | grep -m 1 \"String Im Looking For\""
!
コマンド パイプラインの終了コードを無効にしますgrep -m 1
文字列が見つかったら終了watch -e
エラーが発生した場合に返します
しかし、これまで捨てられていた一致した行を実際に表示するように改善できます。
stdout に継続的に書き込みを行うプログラムを使用している場合は、'single match' オプションを使用して grep にパイプするだけです。 grep は一致する文字列を見つけると終了し、grep にパイプされているプロセスの stdout を閉じます。このイベントはすべき プロセスが再び書き込みを行う限り、自然にプログラムを正常に終了させます .
grep が終了した後にクローズされた stdout に書き込もうとすると、プロセスは SIGPIPE を受け取ります。以下は ping を使用した例です。それ以外の場合は無期限に実行されます:
$ ping superuser.com | grep -m 1 "icmp_seq"
このコマンドは、最初に成功した 'pong' に一致し、次の ping
で終了します。 stdout への書き込みを試みます。
ただし
プロセスが再び stdout に書き込むことが常に保証されているわけではないため、SIGPIPE が発生しない可能性があります (たとえば、これはログ ファイルをテーリングするときに発生する可能性があります)。このシナリオで私が思いついた最善の解決策は、ファイルへの書き込みです。改善できると思われる場合はコメントしてください:
$ { tail -f log_file & echo $! > pid; } | { grep -m1 "find_me" && kill -9 $(cat pid) && rm pid; }
内訳:
<オール>tail -f log_file & echo $! > pid
- ファイルを追跡し、プロセスをバックグラウンドにアタッチし、PID を保存します ($!
) ファイルに。代わりに PID を変数にエクスポートしようとしましたが、ここと PID が再び使用されるときとの間に競合状態があるようです.{ ... ;}
- これらのコマンドをグループ化して、現在のコンテキストを維持しながら出力を grep にパイプできるようにします (変数を保存して再利用するときに役立ちますが、その部分を機能させることができませんでした)|
- 左側の標準出力を右側の標準入力にパイプli> grep -m1 "find_me"
- 目的の文字列を見つける&& kill -9 $(cat pid)
- tail
を強制終了 (SIGKILL) 処理 後 grep
一致する文字列が見つかったら終了します&& rm pid
- 作成したファイルを削除