ln -s . aa
を使用して、現在のディレクトリにシンボリックリンクを追加しました。 cd aa
を実行し、その後pwd
を実行すると、応答は/home/sim/aa
になります。
しかし、/bin/pwd
を実行すると、/home/sim
が出力されます(現在のディレクトリは変更されていません)。
この違いはどこから来るのですか?
Bashを含むほとんどのシェルでは、pwd
はシェル組み込みです。
$ type -a pwd
pwd is a Shell builtin
pwd is /bin/pwd
/bin/pwd
を使用する場合は、-L
オプションを使用して、組み込みpwd
と同じ結果を取得する必要があります。
$ ln -s . test
$ cd test && pwd
/home/cuonglm/test
$ /bin/pwd
/home/cuonglm
$ /bin/pwd -L
/home/cuonglm/test
デフォルトでは、/bin/pwd
はシンボリックリンクを無視し、実際のディレクトリを出力します。
info pwd
から:
`-L'
`--logical'
If the contents of the environment variable `PWD' provide an
absolute name of the current directory with no `.' or `..'
components, but possibly with symbolic links, then output those
contents. Otherwise, fall back to default `-P' handling.
`-P'
`--physical'
Print a fully resolved name for the current directory. That is,
all components of the printed name will be actual directory
names--none will be symbolic links.
組み込みのpwd
にはデフォルトでシンボリックリンクが含まれていますが、-P
オプションが使用されているか、-o physical
set組み込みが有効になっています。
man bash
から:
pwd [-LP]
Print the absolute pathname of the current working directory.
The pathname printed contains no symbolic links if the -P option
is supplied or the -o physical option to the set builtin command
is enabled. If the -L option is used, the pathname printed may
contain symbolic links. The return status is 0 unless an error
occurs while reading the name of the current directory or an
invalid option is supplied.
プロセスがファイルシステムに問い合わせて、現在の作業ディレクトリを特定することは可能です。この質問に対する回答としてトピックにするには少し複雑すぎる方法を使用します。これは、pwd
プログラムとgetcwd
ライブラリ関数が行うことです。 Unixの初期の頃は、作業ディレクトリが何であるかを見つける唯一の方法でした。これは、他の回答、またはこのサイトの他のどこにも私が見つけることができない、あなたの質問に対する回答の一部です(42秒相当の検索の後)。
getcwd
を呼び出すことにより)。その後、cd
、pushd
、またはpopd
を実行すると、シェルが追跡します文字列操作関数を使用して作業ディレクトリの。例えば、
/home/sim
で、cd ..
と入力すると、シェルは作業ディレクトリが/home
であると計算します。/home/sim
で、cd .
と入力すると、シェルは作業ディレクトリが/home/sim
であると計算します。/home/sim
で、cd aa
と入力すると、シェルはaa
がシンボリックリンクかどうかを確認せずに、作業ディレクトリが/home/sim/aa
であると計算します。これは、getcwd
を呼び出す「コスト」を節約するために行われます。しかし、これは不正確な情報をもたらす可能性があるため、トレードオフです。
pwd
(組み込み)コマンドは、作業ディレクトリが何であるかをシェルが記憶/計算した概念を表示するだけです。要するに、シェルはそれがどこにあるのか混乱する可能性があるということです。ただし、/bin/pwd
と入力すると、シェルの作業ディレクトリの概念にアクセスできない別のプロセスで実行されるため、昔ながらの方法で実際の作業ディレクトリ自体が決定されます。 (例外:/bin/pwd
プログラムcanはPWD環境変数を確認できますが、-L
を指定すると明らかに実行されます。)シェルが混乱する別の例を次に示します。
cd /home/sim/aa #
/home
、/home/sim
、および/home/sim/aa
#
はすべて実際のディレクトリです(シンボリックリンクではありません)。pwd #
出力:/home/sim/aa
、これは正しいです。mv ../aa ../bb
pwd #
出力:/home/sim/aa
、これは正しくありません。/bin/pwd #
出力:/home/sim/bb
、これは正しいです。
そして、これが明確でない場合に備えて、ln -s . aa
およびcd aa
と入力すると、現在の作業ディレクトリは変更されません、cd .
を入力したときのそれ以上–これは、cd aa
を入力したときの本質的なことです。