
一部のテキストが表示されるまでファイルを表示したいです。
私はこの答えを見つけました:テキストが表示されるまで `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
答え1
これは次のとおりです。
存在する:
cmd1 | cmd2
cmd1
シェルが終了してもcmd2
終了するまで待ちます。すべての殻がこのようなわけではありません。たとえば、BourneやKornなどの一部のシェルはそうではありません。
死んだときのcmd2
標準出力のパイプはcmd1
次のようになります。壊れたしかし、cmd1
すぐに終了するわけではありません。
cmd1
次回パイプに書き込もうとすると終了します。その後、SIGPIPEを受け取り、基本的な作業はプロセスを終了することです。
cmd1
==tail -f file
とcmd2
==を使用すると、sed /w/q
ファイルtail -f
の最後の10行を読み取り、stdout(パイプ)に書き込みます。通常、行が大きすぎてより多くのテキストが追加されるのを待たない限り、ブロックに書き込まれますfile
。
sed
同時に実行されるは、標準入力から入力を待ち、読み取り、1行ずつ処理しますw
。
行が見つかると(または一部の実装では単一の行遅延がある可能性がありますsed
)、終了しますが、それ以降は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以降、フォローモードのGNU実装は、tail
新しいデータを監視するファイルをポーリングするだけでなく、stdoutが破損したパイプになったことを確認してすぐに終了します(または1秒以内に終了する場合)。inotify使用されません)、上記の回避策は不要になります。
ただし、tail
これはGNUだけが行い、他の実装tail
(私が知っている限り)や他のユーティリティ(GNU実装ではない)は実行しないことに注意してください。
したがって、同時に:
tail -f file | head -n1
1行後に終了します。
tail -f file | tr '[:lower:]' '[:upper:]' | head -n1
たとえば、tr
パイプが破損していることを確認するために標準出力を必ず監視する必要はないため、破損した場合にのみ終了します。書くいつものように、パイプが壊れた後に何かが起こります(その後、tail -f
GNUは終了します)。