少しテキストが表示されるまでファイルを見たい
私はこの答えを見つけました:テキストが表示されるまで `tail -f`
しかし、ubuntuで試してみたところ、終了しません:
$ echo one > test.txt
$ echo two >> test.txt
$ echo three >> test.txt
$ echo four >> test.txt
$ cat test.txt | sed '/w/ q'
one
two
$
期待どおりに動作します。ただし、ファイルをテール化しようとすると
$ tail -f test.txt | sed '/w/ q'
one
two
それは決して終了しません。パイプが壊れても尻尾が止まらない。
tail
の作り方を知っている人はいますか sed
で終了 終了しますか?
承認された回答:
と同じです:
- パイプを閉じるときに早く終了するにはどうすればよいですか?
- 一致を見つけた後、Grepの終了が遅いですか?
- 出力の検索を制限し、信号13を回避します
で:
cmd1 | cmd2
シェルはたまたまcmd1
まで待機します cmd2
の後でも終了します すでに終了しています。すべてのシェルに当てはまるわけではありません。たとえば、ボーンやコーンのシェルのようなものはそうではありません。
cmd2
の場合 死ぬ、cmd1
のパイプ のstdoutが壊れたになります 、ただし、cmd1
は終了しません 即座に。
cmd1
次にそのパイプに書き込もうとしたときに終了します。その後、デフォルトのアクションがプロセスを終了することであるSIGPIPEを受け取ります。
cmd1
を使用 ==tail -f file
およびcmd2
==sed /w/q
、tail -f
ファイルの最後の10行を読み取り、stdout(パイプ)に書き込みます。行が本当に大きく、file
に追加されるテキストが追加されるのを待つ場合を除いて、通常は1つのチャンクで書き込みます。 。
sed
は同時に実行され、stdinでの入力を待機し、それを読み取り、1行ずつ処理し、w
を含む行がある場合は終了します。 。
すぐに(または、sed
で1行の遅延が発生する可能性があります 実装)その行を見つけると終了しますが、その時点でtail
は、書き込みに必要なすべてのパイプにすでに書き込みを行っているため、後でファイルに追加のテキストが追加されない限り、SIGPIPEを受信しません(その時点で、致命的なwrite()
が実行されます。 。
cmd1
が必要な場合 cmd2
ですぐに終了します 終了したら、cmd2
を一度殺すために何かが必要になります 終了します。のように:
sh -c 'echo "$$"; exec tail -f test.txt' | {
IFS= read pid
sed /w/q
kill -s PIPE "$pid"
}
またはbash
:
{ sed /w/q; kill -s PIPE "$!"; } < <(exec tail -f text.txt)
2020編集
@ user414777が指摘しているように、バージョン8.28以降、tail
のGNU実装 、フォローモードでは、監視するファイル内の新しいデータをポーリングするだけでなく、そのstdoutが壊れたパイプになり、すぐに終了するかどうかもチェックします( inotify の場合は1秒以内) は使用されません)、上記の回避策は不要です。
ただし、GNUtail
のみに注意してください tail
の他の実装ではなく、この種の処理を行います (AFAIK)であり、他のユーティリティ(GNU実装でさえ)ではありません。
だから、ながら:
tail -f file | head -n1
1行後に終了します
tail -f file | tr '[:lower:]' '[:upper:]' | head -n1
たとえば、必ずしもtr
とは限りません。 stdoutが壊れたパイプになるかどうかを監視しないため、書き込みした場合にのみ死にます。 パイプがいつものように壊れた後、そこに何かがあります(そして、GNU tail -f
がその時点でのみです 終了します)。