pwdと/ bin / pwdの奇妙な違い


15

を使用して現在のディレクトリにシンボリックリンクを追加しましたln -s . aa。実行しcd aa、その後実行した場合pwd、応答はになり/home/sim/aaます。

しかし、実行する/bin/pwdと印刷されます/home/sim(現在のディレクトリは変更されていません)。

この違いはどこから来たのですか?

回答:


17

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.

私はそれらの違いから来るんどこ理解することはよく分からない
user3581976

/bin/pwdデフォルトでシンボリックリンクを無視しinfo pwd、私の答えの一部を読む:現在のディレクトリの完全に解決された名前を出力します。つまり、印刷される名前のすべてのコンポーネントは実際のディレクトリ名になります。シンボリックリンクはありません。
cuonglm 14

@ user3581976:より明確に更新されたものを参照してください。
クオンルム14

デフォルトで設定されているのに、pwdに-Lコマンドがあるのはなぜですか?また、シェルは/ bin / pwdコマンドを使用してpwdを実行しませんか?
user3581976 14

2
@ user3581976:あなたとあなたのシェルを起動することをイメージset -o physical今、pwd使用している-Pあなたが持っていない場合、デフォルトではオプション、-Lオプションを、どのようにパスがシンボリックリンクが含まれている印刷できますか?これhttps://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.htmlを読んで、何をするのかを知ってくださいset -o physical
cuonglm 14

7

プロセスは、この質問に対する答えとしてトピックに入れるには少し複雑すぎる方法を使用して、ファイルシステムに問い合わせて現在の作業ディレクトリを決定することができます。これは、pwdプログラムとgetcwdライブラリ関数が行うことです。Unixの初期には、作業ディレクトリが何であるかを知る唯一の方法でした。ここに、あなたの質問への回答の一部があります。他の回答のどれにも、このサイトの他のどこにも見つかりません(検索の42秒後):

  • シェルが起動すると、現在の作業ディレクトリを取得します(おそらくを呼び出してgetcwd)。
  • その後、いつでもあなたはcdpushdまたはpopd、シェルがトラックに保つ文字列操作関数を使用して作業ディレクトリのを。例えば、

    • 作業ディレクトリがで/home/sim、入力するcd ..と、シェルは作業ディレクトリがであると計算します/home
    • 作業ディレクトリが/home/simあり、入力するcd .と、シェルは作業ディレクトリがまだあると計算します/home/sim
    • 作業ディレクトリがで/home/simあり、を入力するcd aaと、シェルは作業ディレクトリがシンボリックリンクである/home/sim/aaかどうかを確認せずに計算しますaa

    呼び出しの「コスト」を節約するためにこれを行いますgetcwd。しかし、これはトレードオフです。これは、誤った情報をもたらす可能性があるためです。

  • pwd(組み込み)コマンドは、単に作業ディレクトリが何であるかのシェルの思い出した/計算された概念を表示します。
  • また、シェルはユーザープロセスの利便性のために、作業ディレクトリが何であるかを記憶/計算した概念を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 . aaand をタイプしてもcd aa、あなたの現在の作業ディレクトリ、あなたがタイプしたときよりも変わらないcd .- それは、あなたがタイプしたときに本質的にあなたがしていることだからcd aa


ありがとう、非常に良い答え、これは私が待っていたものです;)
user3581976 14

2
この答えは少し曲がっているようです。コストを節約する-Lだけではなく、ユーザー定義のPOSIX指定の環境変数であるため、ユーザー空間アプリケーションはおそらくそれを信頼する必要があります(それが意味するものは何でも...?)。とにかく、私はシンボリックリンクのファンではありませんが、ユーザーが彼らと一緒に選択するのと同じくらい多くのクレイジーな方向に間接的にアクセスすることはユーザーの特権です- それは何よりも重要です。$PWD -L
mikeserv

1
これは受け入れられた答えでなければなりません(シンボリックリンクは問題のポイントではありません)。
トーマスディッキー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.