「tail -f ... | tail」が出力を生成しないのはなぜですか?

「tail -f ... | tail」が出力を生成しないのはなぜですか?

次のコマンドが出力を生成しないのはなぜですか?

$ tail -f /etc/passwd | tail

について読んだ後バッファー、私は成功せずに次のことを試しました。

$ tail -f /etc/passwd | stdbuf -oL tail

以下は出力を生成します。

$ tail /etc/passwd | tail

これも本当です:

$ tail -f /etc/passwd | head

私はtailバージョン8.21(GNU coreutils)を使用しています。

答え1

tail -f尾は実は現在としては知られていないのですが、tail次にはどうやって知ることができますか?一方、tail -fヘッダーは既知であるため処理できます。

あるいは、より簡単に言えば、tailファイルの終わりに基づいていますが、出力ストリームtail -fにEOFはありません(少なくとも終了する前ではありません)。

最初のpidを見つけてtail殺すと、次のことを行う必要があります。それから2番目の出力を参照してください。

答え2

技術ソリューション

ストリームを入力として実行すると、ストリームを読み取るときに埋められるラインバッファは保持されtailますが、nストリームの終わりに達するまでラインを出力することはできません。つまり、EOFストリームから読み取ろうとすると、特別なコードが受信されます。入力ストリーム。呼び出しがtail -f終了しないため、ストリームを閉じないため、ストリームの最後の10行を返すことはできません。

答え3

tail最後のX行を表示します。 tail -f同じことを行いますが、本質的に無限ループです。起動時にファイルの最後のX行を表示し、いくつかのOSマジック(inotifyなど)を使用して新しい行を監視して表示します。

その仕事をうまく行うためにtailファイルの終わりが見つかるはずです。tailファイルの終わりが見つからない場合は、「last」が定義されていないため、最後のX行を表示できません。それでは、tailこの状況で何をすべきですか?ファイルの終わりが見つかるまで待ちます。

考えてみてください:

$ chatter() { while :; do date; sleep 1; done; }
$ chatter | tail -f

なぜならchatter

tailファイルシステムパイプの最後の数行を要求すると、同じ動作が得られます。考慮する:

$ mkfifo test.pipe
$ tail test.pipe

stdbuf既知の問題を解決する高貴な試みです。ただし、重要な事実は、I/O バッファリングが根本的な原因ではなく、明示的なファイルの終わりがないことです。見たらtail.c ソースコードfile_lines、次のように関数コメントが表示されます。

END_POSはEOFのファイルオフセットです(最後のバイトのオフセットより1大きい)。

それがまさに魔法です。すべての設定でtailが機能するには、ファイルの終わりが必要です。 headこれらの制限がない場合は、ファイルの先頭のみが必要です(そうでない可能性がある、try head test.pipe)。sedなどのストリーム指向ツールは、awkファイルの先頭や終了を必要とせず、バッファで機能します。

答え4

この機能は、tail入力またはファイルの最後の部分である「尾」を表示することです。 (このオプションは-f後で行うことに関するものであるため、ここでは関係ありません。)

ファイルを考えてみましょう:

何ですかファイルの最後の部分
これが次のとおりです。最後のn行ファイルの。

入力ファイルから1行を読み取るときにiそれを印刷する必要があるかどうかを判断するにはどうすればよいですか?
私たちはそれが最後の部分にあるかどうかはわかりません。なぜなら、最後の行が何になるのか分からないからです。だから私たちはできない今印刷してください。

私たちはする必要があります並ぶこれが最後の数行の一部であるnか、より多くの行がわかっているため、最後の数行の一部ではないことが明らかになるまでn

今来たらファイルの終わり、私たちはn私たちが保存した最後の数行が実際にnファイルの最後の数行であることを知っています。

今この場合

tail -f /etc/passwd | tail

まずtailファイルを読んでから待ってください。より多くのデータを取得するそれも書いてください。だからそうだろうファイル終了信号をエクスポートしないファイルが終わったら、2番目の尾まで読みます。これはありません、2番目tail 通知を受け取らないファイルの終わりなので、次のことができます。決して把握できないだろう印刷する最後の数行です。

関連情報