を使用して現在のディレクトリにシンボリックリンクを追加しましたln -s . aa
。実行しcd aa
、その後実行した場合pwd
、応答はになり/home/sim/aa
ます。
しかし、実行する/bin/pwd
と印刷されます/home/sim
(現在のディレクトリは変更されていません)。
この違いはどこから来たのですか?
を使用して現在のディレクトリにシンボリックリンクを追加しました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
オプションを使用してbuiltinと同じ結果を取得する必要があります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
設定が有効にされることを除いて、デフォルトでシンボリックリンクが含まれます。
から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.
/bin/pwd
デフォルトでシンボリックリンクを無視しinfo pwd
、私の答えの一部を読む:現在のディレクトリの完全に解決された名前を出力します。つまり、印刷される名前のすべてのコンポーネントは実際のディレクトリ名になります。シンボリックリンクはありません。
set -o physical
今、pwd
使用している-P
あなたが持っていない場合、デフォルトではオプション、-L
オプションを、どのようにパスがシンボリックリンクが含まれている印刷できますか?これhttps://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html
を読んで、何をするのかを知ってくださいset -o physical
。
プロセスは、この質問に対する答えとしてトピックに入れるには少し複雑すぎる方法を使用して、ファイルシステムに問い合わせて現在の作業ディレクトリを決定することができます。これは、pwd
プログラムとgetcwd
ライブラリ関数が行うことです。Unixの初期には、作業ディレクトリが何であるかを知る唯一の方法でした。ここに、あなたの質問への回答の一部があります。他の回答のどれにも、このサイトの他のどこにも見つかりません(検索の42秒後):
getcwd
)。その後、いつでもあなたはcd
、pushd
またはpopd
、シェルがトラックに保つ文字列操作関数を使用して作業ディレクトリのを。例えば、
/home/sim
、入力するcd ..
と、シェルは作業ディレクトリがであると計算します/home
。/home/sim
あり、入力するcd .
と、シェルは作業ディレクトリがまだあると計算します/home/sim
。/home/sim
あり、を入力するcd aa
と、シェルは作業ディレクトリがシンボリックリンクである/home/sim/aa
かどうかを確認せずに計算しますaa
。呼び出しの「コスト」を節約するためにこれを行いますgetcwd
。しかし、これはトレードオフです。これは、誤った情報をもたらす可能性があるためです。
pwd
(組み込み)コマンドは、単に作業ディレクトリが何であるかのシェルの思い出した/計算された概念を表示します。要するに、シェルはそれがどこにあるかについて混乱する可能性があるということです。ただし、を入力する/bin/pwd
と、作業ディレクトリが何であるかというシェルの概念にアクセスできない別のプロセスで実行されるため、実際の作業ディレクトリ自体が昔ながらの方法で決定されます。(例外:/bin/pwd
プログラムは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
and をタイプしてもcd aa
、あなたの現在の作業ディレクトリは、あなたがタイプしたときよりも変わらないcd .
- それは、あなたがタイプしたときに本質的にあなたがしていることだからcd aa
。
-L
だけではなく、ユーザー定義のPOSIX指定の環境変数であるため、ユーザー空間アプリケーションはおそらくそれを信頼する必要があります(それが意味するものは何でも...?)。とにかく、私はシンボリックリンクのファンではありませんが、ユーザーが彼らと一緒に選択するのと同じくらい多くのクレイジーな方向に間接的にアクセスすることはユーザーの特権です- それは何よりも重要です。$PWD
-L