なぜ「tail -f…| テール」は出力を生成できませんか?


36

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

$ tail -f /etc/passwd | tail

バッファリングについて読んだ後、私は次のことを試してみました:

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

以下が出力を生成することに注意してください。

$ tail /etc/passwd | tail

これもそうです:

$ tail -f /etc/passwd | head

テールバージョン8.21(GNU coreutils)を使用しています。


17
πの最後の10桁は何ですか?
キーストンプソン

回答:


15

私はすべてをUNIXで見たと思った。この質問は、私の独善性から私を平手打ちした。なんて素晴らしい質問でしょう!

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

その仕事tailをするために、ファイルの終わりを見つけることができなければなりません。tail「最後」が定義されていないため、ファイルの終わりが見つからない 場合、最後の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その制限はありません。ファイルの開始だけが必要です(開始しない場合もありますhead test.pipe)。指向のようなツールのストリーミングsedawk必要性もないファイルの開始または終了を:彼らは、バッファに取り組んでいます。


37

tail -fの尾は実際には現時点では不明なものなので、次の尾はどうやっtailてそれを知る必要があります。一方、tail -fの頭はすでに知られているものであり、そのため処理することができます。

または、より単純に言うtailと、ファイルの終わりに相対的ですが、の出力ストリームにtail -fはEOFがありません(少なくともその終了前は)。

あなたが最初に発見した場合tailのPIDをし、それを殺す、次のことを行う必要があり、その後第二の出力を参照してください。


21

技術的な答え

ストリームを入力として実行する場合、ストリームを読み込むときに満たす-lineバッファーをtail保持nしますが、ストリームの最後に到達するまでそれらの行を出力できません。つまりEOF、入力から読み込むときに特別なコードを受け取りますストリーム。呼び出しtail -fは終了しないため、ストリームを閉じることはないため、たとえば、そのストリームの最後の10行を返すことはできません。


3

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

ファイルについて考えてみましょう。

ファイルの最後の部分は何ですか?
それがファイルの最後のn行だとしましょう。

i入力ファイルの行を読むとき、それを印刷する必要があるかどうかを決定する方法は?
最後の行にあるかどうかはわからないため、最後の部分にあるかどうかはわかりません。そのため、現在印刷できません

それが最後の行の一部であるか、それ以上は行がわからないため、その行の一部ではなくなることが明らかになるまで、行保持する必要があります。nn

ここでファイルの最後にn到達すると、保持した最後のn行が実際にファイルの最後の行であることがわかります。

さて、

tail -f /etc/passwd | tail

最初tailにファイルを読み取り、それからさらにデータ取得し、それを書き出すのを待ちます。そのため、読み取るファイルの終わりになると、ファイルの終わりを2番目のテールに通知しません。これがないと、2番目のファイルにはファイルの終わりtail が通知されることはないので、どの行が印刷されるべきかを見つけることはできません

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.