tail
25GBのテキストファイルが必要な場合、tail
このコマンドはファイル全体を読み込みますか?
おそらくファイルがディスクのあちこちに散らばっているのでそうだろうと思いますが、内部がこれであることはよく理解できません。
答え1
いいえ、tail
ファイル全体を読み取るのではなく、最後まで見てから、予想される行数に達するまで後ろにチャンクを読み、ファイルの最後まで正しい方向に行を表示し、ファイルの監視を続行することもできます。-f
対応するオプションが使用されます)。
ただし、tail
ナビゲートできない入力が提供された場合は、パイプから読み取る場合など、データ全体を読み取るしかないことに注意してください。
同様に、ファイルの先頭から始まる行を探すように求められたときに構文または標準以外のオプションを使用してサポートされている場合は、tail -n +linenumber
明らかtail +linenumber
にtail
ファイル全体を読みます(中断されない限り)。
答え2
tail
どのように機能するかを直接確認できます。ご覧のとおり、私のファイルの1つがread
3回実行され、合計約10Kバイトを読みました。
strace 2>&1 tail ./huge-file >/dev/null | grep -e "read" -e "lseek" -e "open" -e "close"
open("./huge-file", O_RDONLY) = 3
lseek(3, 0, SEEK_CUR) = 0
lseek(3, 0, SEEK_END) = 80552644
lseek(3, 80551936, SEEK_SET) = 80551936
read(3, ""..., 708) = 708
lseek(3, 80543744, SEEK_SET) = 80543744
read(3, ""..., 8192) = 8192
read(3, ""..., 708) = 708
close(3) = 0
答え3
ファイルがディスクに分散されているので、[ファイルを順番に読み取らなければならない]必要があるようですが、このような内部はよく理解できません。
これまで知っているように、tail
ファイルの終わりを見つけて(システムコールを使用してlseek
)逆方向に作業するだけです。しかし、上記のコメントで気になったことは「tailはディスク上のファイルの終わりを見つけることができる場所をどうやって知ることができますか?」
答えは簡単です。 Tailは知りません。ユーザーレベルのプロセスはファイルを連続ストリームとして扱うため、誰もがファイルの先頭のtail
オフセットを知ることができます。ただし、ファイルシステムでは、ファイルの「inode」(ディレクトリエントリ)は、ファイルデータブロックの物理的な場所を示す数値リストに関連付けられます。ファイルを読み取ると、カーネル/デバイスドライバは必要な部分を特定し、ディスク上の対応する場所を決定してインポートします。
これが私たちのオペレーティングシステムの目的です。したがって、ファイルブロックがどこに散らばっているのか心配する必要はありません。
答え4
あなたのようにソースコード525行目で実装コメントを見ることができます。
/* Print the last N_LINES lines from the end of file FD.
Go backward through the file, reading 'BUFSIZ' bytes at a time (except
probably the first), until we hit the start of the file or have
read NUMBER newlines.
START_POS is the starting position of the read pointer for the file
associated with FD (may be nonzero).
END_POS is the file offset of EOF (one larger than offset of last byte).
Return true if successful. */