作業ディレクトリを移動するとき、Bashはどのように正しく機能しますか?

作業ディレクトリを移動するとき、Bashはどのように正しく機能しますか?

Linuxでは、あるディレクトリを別のディレクトリに移動し、mv別のシェルでは作業ディレクトリが移動されたディレクトリになります。

そのシェルで実行hg pullしましたcd

どのように動作しますか?

答え1

ファイルまたはディレクトリを移動すると、ファイルツリー内の対応する親エントリを識別するメタデータ属性が変更されますが、実際のノードIDは変更されません。物理ディスクではまだ同じ場所にあり、ファイルシステムはそれをまだ同じオブジェクトと見なします。ファイルまたはディレクトリポインタが開かれている場合は、どこでもすでにオブジェクトに接続されており、オブジェクトのメタデータへの変更は開くプロセスには影響しません。ファイルシステムパスに基づいて新しいポインタを開こうとすると、問題が発生します。

同じ理由で、書き込み中のファイルを移動でき、書き込みは新しい場所に進みます。これは、実際には同じファイルノードであり、ファイル構造内の別の場所に再接続されるためです。ディスクの物理的な場所やノードIDは変更されず、ファイルシステムは単にディスク上のノードの内部マッピングをファイルシステムのパスに更新します。

また、この動作は、移動されたオブジェクトが同じファイルシステムにある場合にのみ適用されます。あるインストールから別のインストールに移動すると、ノードの物理的な場所を変更する必要があり、オブジェクトは元のファイルシステムから削除され、デッドポインタが残ります。

答え2

Unixカーネルは各プロセスの作業ディレクトリを追跡します。マウントされたボリュームにCDを挿入し、マウントポイントからrootとしてコマンドを実行してumountそれを証明できます。デバイス使用量に関するいくつかのメッセージが表示されます。

明らかに、最新のシェルには作業ディレクトリと呼ばれるものがあります。そうしないと、シェルのサブルーチン(C、Pythonなど)がコマンドラインに相対パスを指定したときに正しいファイルを開くことができません。

しかし、最新のシェル(ksh、bash、zshなど)は作業ディレクトリでゲームをプレイします。中間層のどこかにシンボリックリンクを持つディレクトリツリーを作成することでこれを実証できます。

% mkdir a
% cd a
% mkdir b.orig
% ln -s b.orig b
% mkdir b.orig/c
% cd .. 
% cd a/b/c
% pwd
/home/bediger/a/b/c

これがzshのすべてです。シンボリックリンクに沿ってツリーをバックアップし、「..」ディレクトリを使用して動作している場合は見つかります。a/b.orig/c

関連情報