web-dev-qa-db-ja.com

Linuxシステムで開いているファイルはどのように動作しますか?

ログファイルの名前を「foo.log.old」に変更し、アプリケーションが「foo.log」に新しいログファイルの書き込みを開始すると想定しました。ログファイルを新しい名前で追跡し、 "foo.log.old"に行を追加し続けていることに気づいて驚いた。

Windowsでは、私はこの種の振る舞いに精通していません-それを実装することさえ可能かどうかわかりません。この動作はLinuxでどの程度正確に実装されていますか?詳細はどこで確認できますか?

18
ripper234

プログラムは、ファイルシステム(従来のUNIXファイルシステムではiノードと呼ばれます)によって維持されている番号を介してファイルに接続します。この名前は単なる参照です(おそらく一意の参照ではありません)。

したがって、いくつかの注意点があります。

  1. mvを使用してファイルを移動しても、ファイルシステム間でファイルを移動しない限り、その基になる番号は変更されません(これは、元のファイルでcpを使用してからrmを使用するのと同じです)。
  2. 複数の名前が1つのファイルに接続できるため(つまり、ハードリンクがあるため)、「削除された」ファイルのデータはall基になるファイルへの参照がなくなるまで消えません。
  3. おそらく最も重要なことは、プログラムがファイルをopensするとき、そのファイルへの参照を作成することです(データが削除されるときの目的で)、ファイル名が接続されているのと同じです。

これにより、次のようないくつかの動作が発生します。

  • プログラムはファイルを読み取るためにopenできますが、ユーザーがコマンドラインでrmedした後、実際に読み取ることはできませんそしてプログラムは引き続きデータにアクセスできます
  • 発生した問題:ファイルをmvingしても、ファイルとそのファイルを開いているすべてのプログラムとの関係は切断されません(ファイルシステムの境界を越えて移動しない限り、その場合でも、プログラムには元のバージョンが機能します)オン)。
  • プログラムが書き込み用にファイルをopenedし、ユーザーがコマンドラインでそのファイルの最後のファイル名をrmsした場合、プログラムはファイルに内容を書き込むことができますが、閉じるとすぐにそのデータへの参照はなくなり、削除されます。
  • 1つまたは複数のファイルを介して通信する2つのプログラムは、openingが完了した後にファイルを削除することにより、大まかな部分的なセキュリティを取得できます。 (これは実際セキュリティマインドではありません。ギャップのある穴を競合状態に変換するだけです。)

この動作がどのように実装されているかを実際に確認するには、Unixプログラミングの本をいくつか見てください。 Mathepicは、iノードに関連しているという点で正しいです。実際のパス名は、ファイルを開くためにのみ使用されます。これが完了すると、プログラムは開かれたファイル記述子によってファイルを参照します。次に、ファイル記述子はiノードを参照します。この場合、基礎となるファイル名が変更されているかどうかは関係ありません。

これをWindowsに実装する限り、それは別のサイトにとっての問題です。

本を読まずにこれについてもっと読むには、Linuxファイルシステムとiノードを検索してください。明確な答えはないかもしれませんが、その理由は理解できます。

1
Mr. Shickadance