壊れたパイプでtail -fシャットダウンを実行します。

壊れたパイプでtail -fシャットダウンを実行します。

一部のテキストが表示されるまでファイルを表示したいです。

私はこの答えを見つけました:テキストが表示されるまで `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 filecmd2==を使用すると、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 -fGNUは終了します)。

おすすめ記事