回答:
私はすべてを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
)。指向のようなツールのストリーミングsed
やawk
必要性もないファイルの開始または終了を:彼らは、バッファに取り組んでいます。
の機能はtail
、入力またはファイルの最後の部分-「テール」を表示することです。(オプション-f
は後で行うことに関するものなので、ここでは関係ありません。)
ファイルについて考えてみましょう。
ファイルの最後の部分は何ですか?
それがファイルの最後のn行だとしましょう。
i
入力ファイルの行を読むとき、それを印刷する必要があるかどうかを決定する方法は?
最後の行にあるかどうかはわからないため、最後の部分にあるかどうかはわかりません。そのため、現在は印刷できません。
それが最後の行の一部であるか、それ以上は行がわからないため、その行の一部ではなくなることが明らかになるまで、行を保持する必要があります。n
n
ここでファイルの最後にn
到達すると、保持した最後のn
行が実際にファイルの最後の行であることがわかります。
さて、
tail -f /etc/passwd | tail
最初tail
にファイルを読み取り、それからさらにデータを取得し、それを書き出すのを待ちます。そのため、読み取るファイルの終わりになると、ファイルの終わりを2番目のテールに通知しません。これがないと、2番目のファイルにはファイルの終わりtail
が通知されることはないので、どの行が印刷されるべきかを見つけることはできません。