sedが文字列を見つけたときに尾を止める方法は? [コピー]

sedが文字列を見つけたときに尾を止める方法は? [コピー]

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|POLLINPOLLERR

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

それでは、すべてが正常に見えます。そうでない場合は、期待していることを教えてください。とにかく、今後使用する素晴らしい新しいトリックを学んでくれてありがとう!

関連情報