web-dev-qa-db-ja.com

ログプログラムはどのようにして削除されたファイルにログを記録し続けることができますか?

nix Power Tools、3rd Edition から:ファイルを削除する代わりに、空にするセクション:

アクティブなプロセスがファイルを開いている場合(ログファイルでは珍しいことではありません)、ファイルを削除して新しいファイルを作成しても、ロギングプログラムには影響しません。これらのメッセージは、リンクされなくなったファイルに移動し続けます。ファイルを空にしても関連付けは解除されないため、ロギングプログラムに影響を与えることなくファイルをクリアします。

強調鉱山

プログラムが削除されたファイルにログを記録し続ける理由がわかりません。ファイル記述子エントリがプロセステーブルから削除されないためですか?

12
Geek

ファイルを削除すると、そのファイルへの(iノードへの)リンクが本当に削除されます。誰かがすでにそのファイルを開いている場合、そのファイル記述子を保持し続けます。ファイルはディスク上に残り、スペースを占有します。ファイルへのアクセス権があれば、ファイルの読み書きが可能です。

unlink function は、POSIXによってこの動作で定義されています。

ファイルのリンクカウントが0になり、どのプロセスにもファイルが開かれていない場合、ファイルが占有していたスペースは解放され、ファイルにアクセスできなくなります。最後のリンクが削除されたときに1つ以上のプロセスがファイルを開いている場合、unlink()が戻る前にリンクが削除されますが、へのすべての参照まで、ファイルコンテンツの削除は延期されます。ファイルは閉じられています

その行動のためのこのアドバイス。デーモンはファイルを開いたままにし、削除されたことに気づきません(それが特別に監視している場合を除き、これは一般的ではありません)。それはそれが持っている既存のファイル記述子への書き込みを続けます:ディスク上の(より多くの)スペースを占有し続けますが、書き込むメッセージのどれも見ることができないので、あなたは本当に最悪です両方の世界の。代わりにファイルの長さをゼロに切り詰めると、スペースはすぐに解放され、新しいメッセージはファイルの新しい最後に表示され、そこに表示されます。

最終的に、デーモンが終了するか、ファイルが closes すると、スペースが解放されます。 Linuxの/proc/x/fd/... )。また、次のことが保証されています。

ファイルのリンクカウントが0の場合、そのファイルに関連付けられたすべてのファイル記述子が閉じられると、ファイルによって占有されていたスペースが解放され、ファイルにアクセスできなくなります。

したがって、ディスク領域を永久に失うことはありませんが、ファイルを削除しても何も得られず、新しいメッセージにアクセスできなくなります。

11
Michael Homer

丁度。

ファイルは三者構成です。

  • コンテンツ、つまりディスクのどこかに書き込まれた、またはオンザフライで生成されたバイトのフラットアレイ。
  • インデックスノード、または略してinodeは、カーネルによって入力および使用されるデータ構造です。これには、ファイルに関するすべてのメタデータ(サイズ、権限など)と、ファイルのコンテンツの場所へのポインターが含まれます。
  • 1つ以上のディレクトリエントリ、これは場所であり、_pathsのように操作されます/home/user/personal_file、これは、ファイルの使用、コンテンツの変更、メタデータの変更などを行うためのハンドルとして機能します。

ファイルを開くときに、オペレーティングシステムへのパスを指定すると、iノードに直接ハンドルが返されます。このファイル記述子と呼ばれるハンドルを使用すると、必要に応じて(または少なくともOSで許可されているとおりに)ファイルを操作できます。

Iノードを直接削除することはできません。削除を要求するには、OSにpathを指定する必要があります。したがって、ファイルを削除する場合は、ディレクトリエントリのみを削除します。ファイルに他のディレクトリエントリがある場合、そのファイルには引き続きアクセスできます。アクセスできない場合でも、そのファイルを指しているファイル記述子がある間は、そのiノードは削除されません。 @MichaelHomerの回答は、この特定のトピックについてより技術的で詳細です。

8
lgeorget

他の2つの回答は問題をよく説明しています。ファイルは、そのファイルへのすべてのディレクトリリンクandへのリンクがすべて解除されるまで「削除」されません。

これを回避するには、使用することをお勧めします

> /var/log/bigfile

の代わりに

rm -f /var/log/bigfile

これは、コンテンツを削除するのではなく、0バイトにリセットするだけなので、書き込まれた内容を確認できます。

ファイルを削除し、Linuxで/ proc/fdファイルシステムを使用している場合は、引き続き使用できます

> /proc/12345/fd/3

ファイルの内容をゼロにします(12345がプロセスIDで、3が大きなファイルのfd番号であると仮定します)。これは、ディスクがフル稼働していて、何らかの理由でログファイルを書き込んでいるプロセスを強制終了できない場合に、命の恩人になることができます。