web-dev-qa-db-ja.com

ディレクトリシンボリックリンクトラバーサルと親ディレクトリを理解する

ディレクトリ/dir1/dir2/linkedがあり、後者は前者へのシンボリックリンクであるとします。

cdからlinkedおよびpwdに移動すると、出力/dir2/linkedが得られます。その後、cd ..を実行すると、/dir2になります。この動作は、以前に/dir2/linkedにいるという概念と一致しています。ただし、私が理解しているように、任意のディレクトリの親ディレクトリ(..)は、ディレクトリiノード(つまり、物理的にはディスク)に格納されます。明らかに、/dir2/linkedは実際には/dir1であるため、iノードの親ディレクトリは/である必要があります。

さらに複雑なことに、/dir2/linked内では、ls ..cd .. ; ls .の出力が異なります。 cdはシンボリックリンクされたパスを尊重し、lsは「物理的な」パスを尊重するようです。 この質問 で述べたように、このユースケースにはcd -Pがあります。

man pwdは「物理的」および「論理的」な作業ディレクトリについて言及していますが、現時点ではまだいくつか質問があります。

  • man pwdで説明されているように、この動作は常にPWD環境変数によって提供されますか?
  • デフォルトのcdlsが両方ともシェルコマンド(つまり、プログラムではない)である場合、なぜ異なる動作をするのですか?
  • 典型的なプログラム(シェルコマンドではない)は、物理パスの代わりにPWDを使用しますか?実装次第だと思いますが、経験則はありますか?
9
goncalopp

bashは、シンボリックリンクを「認識」し、シンボリックリンクを使用してディレクトリに入るときにこの情報を追跡します。

これを確認するには、例で次の手順を実行します。

$ cd /dir2
$ cd linked
$ pwd
/dir2/linked
$ PWD='' bash -c pwd
/dir1

空のPWD変数でbashを開始する必要があります。そうしないと、そのトリックを使用して「偽の」パスが表示されます。

lsis別のプログラムであるため、現在のディレクトリにどのように到達したかについてbashの知識がないことに注意してください。したがって、ls ..は、フォローしたシンボリックリンクに関連するものではなく、real親ディレクトリの内容を表示するだけです。

プログラムを起動する方法はたくさんあるので、ほとんどのプログラムは環境変数CWDに依存しません。bashシェルは1つしかないため、CWDに正しい値が含まれていると期待するのは信頼できません(試してみてください)。 CWDbash -c pwd、正気度の値をチェックしていることがわかります)。

5
wurtel