2つのシェルを開いています。 1つ目はディレクトリAにあります。2つ目は、ディレクトリAを削除して、再作成します。最初のシェルに戻ってls
と入力すると、出力は次のようになります。
ls: cannot open directory .: Stale file handle
どうして?最初のシェル(存在しないディレクトリ内で開いたままのシェル)は、次のコマンドを待っている間に「フリーズ」し、ディレクトリが削除されて再作成されたことを「認識」しなかったと思いました。シェルは、文字列$PWD
以外の現在の作業ディレクトリへの「より深い」参照を保持していますか?
ディレクトリ(他のファイルと同様)はその名前で定義されていません。名前をディレクトリのアドレスと考えてください。ディレクトリを移動しても、別の家に移動した場合と同じように、同じディレクトリのままです。ディレクトリを削除して同じ名前で新しいディレクトリを作成すると、以前住んでいた家に引っ越してきた人があなたではないように、それは新しいディレクトリになります。
各プロセスには 作業ディレクトリ があります。シェルのcd
コマンドは、シェルの現在の作業ディレクトリを変更します。 pwd
コマンドは、現在の作業ディレクトリへの¹パスを出力します。
ディレクトリAを削除したとき、これは親ディレクトリのAのエントリを削除することでした。ディレクトリA自体はファイルシステムに残りましたが、名前のない切り離された状態でした。プロセス、つまり最初のシェルで使用されていたため、まだ削除されていません。最初のシェルでディレクトリを変更すると、最終的にディレクトリが削除されました。プロセスがまだ開いている間にファイルが削除された場合も同じことが起こります。ファイルのディレクトリエントリはすぐに削除され、ファイル自体は使用が停止すると削除されます。
同様に、ディレクトリを移動するとどうなるかを観察します。
mkdir one two
touch one/1 two/2
cd one
ls
別のシェルで:
mv one tmp
mv two one
mv tmp two
最初のシェルでは:
ls
ファイル 1
は、元々はone
と呼ばれていたディレクトリにあり、現在はtwo
と呼ばれています。ファイル 2
は、元々two
と呼ばれていたディレクトリにあり、現在はone
と呼ばれています。
¹ より正確には、aパス。シンボリックリンクや他の微妙な要素が含まれている場合、一意ではない可能性があります。
新しいディレクトリAはディレクトリAと同じではありません。古いディレクトリを削除する前と新しいディレクトリを作成した後にstat
コマンドで確認でき、異なるiノード番号が表示されます。
そして、これはカーネルの動作に関連していると思います。各プロセスの現在のディレクトリのi番号を追跡するだけです。したがって、異なるi番号があるため、これは異なる衝突につながります。
これは予想される動作です。新しいディレクトリAは古いディレクトリAと同じではなく、たまたま同じ名前になっています。したがって、最初の端末の$ PWDはまだなくなっており、mkdir A
を実行したときに魔法のように再表示されることはありませんでした。
ファイルと同様に、ディレクトリにはiノードが関連付けられています。
307%mkdir A B C
308%ls -i 11997708 A 11997709 B 11997710 C
Iノードは、ディレクトリまたはファイルに関する情報を含むデータ構造です。すべてのディレクトリとファイルに1つあります。それをアドレス(実際にはインデックス番号)と考えてください。
私がAにいる場合、iノード番号11997708で、別のシェル(またはこれから行うのと同じシェル)でディレクトリAを削除してから、それを再作成してiノードをlsします。
309%cd A
310%rmdir ../A
311%mkdir ../A
312%ls -i ..
1199772 A 11997709 B 11997710 C
Iノードは異なるため、削除されたディレクトリAにファイルを作成しようとすると、次のようになります。
313%これに触れる
touch:「this」をタッチできません:そのようなファイルまたはディレクトリはありません
私がいるディレクトリは、iノードに関連付けられていないためです1199772-したがって、現在私がいる場所には、正当なアドレス/インデックスがありません-iノード。したがって、エラー。