私はかなり標準的なtail
+ grep
をやっています:
tail -f some_log_file.txt | grep -q known-string
-q
なしでコマンドを実行した場合:
tail -f some_log_file.txt | grep known-string
出力が表示されます:
[Tue Feb 12 11:32:45 2019] known-string.
だから私はgrepが一致していることを知っています。ただし、-q
を追加すると、grepコマンドが終了せず、出力を待つだけでハングします...マニュアルページに「一致するものが見つかった場合はステータスなしですぐに終了します」と表示されます。
-q, --quiet, --silent Quiet; do not write anything to standard output. Exit immediately with zero status if any match is found, even if an error was detected. Also see the -s or --no-messages option.
-q
が私のgrepを終了させない理由を誰かが説明できますか? && beep
を最後までチェーンしようとしているので、一致するものが見つかるとgrep
がビープ音を鳴らしますが、終了させることができない限り、機能しません。
StackOverflowの投稿から 'grep -q'は 'tail -f'で終了しません :
tail -f
はファイルを読み取り、後で追加された行を表示しますが、終了しません(SIGTERM
のようなシグナルが送信されない限り)。grep
は、ここではブロック部分ではありません、tail -f
です。grep
はパイプが閉じられるまでパイプから読み取りますが、それはtail -f
は終了せず、パイプを開いたままにします。あなたの問題の解決策はおそらく(テストされておらず、パフォーマンスが悪い可能性が非常に高い)でしょう:
tail -f logfile | while read line; do echo $line | grep -q 'find me to quit' && break; done
あなたはリンクされた投稿でより多くの情報と解決策を見つけるでしょう。
grep
は実行を続けますが、tail
は終了し、パイプは消えます。 このバグレポートログ あなたと非常によく似たユースケースから始まります:
tail
とgrep
を使用して、特定のパターンが表示されるまでファイルを追跡したいと思います。ただし、tail
が終了しても、grep
は終了しません。_$ echo xxx > /tmp/blabla $ tail -f /tmp/blabla |grep -m1 --line-buffered "xxx" xxx
_現在、
tail
は、_/tmp/blabla
_に再度書き込んだ場合にのみ、読み取りを試みて終了します。これはどうあるべきか?
そこでの説明:
tail
はSIGPIPEで終了しますが、シグナルはwrite()
でのみ取得されるため、tail
が終了する前にファイル内のデータをさらに取得する必要があります。
私の知る限り、この正確なメカニズムは非常に一般的です。多くのツールはafterを終了し、壊れたパイプに何かを書き込もうとしますが、これはバグではありません。
それからこの願いが来ました:
tail
は永遠にぶらぶらする可能性があるため、パイプのもう一方の端が消えるのに対応するために特別な手順を実行する必要があります。
そして最後に:
実装先:
https://git.sv.gnu.org/cgit/coreutils.git/commit/?id=v8.27-42-gce0415f
実際、tail
from GNU coreutils 8.28で問題を再現しようとすると、できません。ツールはすぐに終了します。