tail
すべての行が別のファイルに書き込まれるまで一致するものを見つけたら、コマンドを終了したいと思います。
tail -f logfile | sed '/special string/q' | tee output.txt
Output.txtには、特殊文字列が見つかるまで行が含まれます。しかし、問題はその後tail
コマンドを終了したいということです。
答え1
明示的に殺す必要があります。
seq 1 10 > file
tail -f file | { sed /7/q; pkill -PIPE -xg0 tail; } | tee output
pkill -PIPE -xg0 tail
方法
私たちと同じプロセスグループに属する
SIGPIPE
プロセスにシグナルを送信します。tail
tail
これは、同じプロセスグループで別のプロセスが実行されていないと仮定します。コマンドが対話型端末(ジョブ制御を含むシェル)で実行される場合、各パイプは独自のプロセスグループ(ジョブとも呼ばれます)で実行されるため、安全でなければなりません。ジョブ制御のないシェル(スクリプトなど)では、ジョブ制御が明示的にオンになっている別のシェルにパイプをラップできます。
sh -mc 'tail -f file | { sed /7/q; pkill -PIPE -xg0 tail; }' | tee output
しかし、GNUテールは自分で死ぬでしょう。
bashとcoreutilsでLinuxボックスを使用すると、すべてが正常で何も必要なく、自動的にシャットダウンkill
されtail
ます。
debian$ tail -f file | sed /2/q
1
2
debian$ # WOW!
tail
これは、GNU coreutilsが標準出力がまだ有効であることを確認するために賢いトリックを使用するためです。書き込み可能:「準備」のポーリング中です。読む「エラーが発生した場合、パイプのもう一方の端が閉じているかのように、パイプの書き込み端でのみ発生する条件です。この場合、信号でtail
簡単に自殺できますSIGPIPE
。 」ソースコード:
FD_SET (STDOUT_FILENO, &rfd);
/* readable event on STDOUT is equivalent to POLLERR,
and implies an error condition on output like broken pipe. */
if (select (STDOUT_FILENO + 1, &rfd, NULL, NULL, &delay) == 1)
die_pipe ();
[実際には他のシステムでこれを実行または置き換えるPOLLHUP
ことができますが、実際には重要ではありません。]POLLHUP|POLLIN
POLLERR
GNUテールは、ソケットやttyではなくパイプでのみこれを行います。つまり、Knee Unixドメインソケットを使用して「パイプ」を実装するksh93では機能しません。
また、私が知っている限り、GNUだけがtail
これを行い、バージョンでのみ可能です。8.28; Linuxでもbusyboxtail
にはありません。
これは、使用tail -f | quit_at_some_point
(ここにある多くの答えで判断)が依然として非常に付随的であり、実際には終わらない可能性があることを意味します。
答え2
次の点を考慮するとlogfile
:
one
two
three
special string
four
そして次のコマンド
$ tail -f logfile | sed '/special string/q' | tee output.txt
次の結果が表示されます。
one
two
three
special string
それから両方 tail
正常にsed
終了しました。したがって、あなたの例(少なくとも私のコンピュータでは)はあなたが説明するものと正確に一致します。これをさらに確認するために、次の文書が提供されます。
one
two
three
four
出力が出ず、コマンドが中断されて待っています。その後、別の端末でコマンドを使用して追加するspecial string
と、元のコマンドは再び正常に終了します。echo special string >> logfile
それでは、すべてが正常に見えます。そうでない場合は、期待していることを教えてください。とにかく、今後使用する素晴らしい新しいトリックを学んでくれてありがとう!