現在のディレクトリを削除するときのbashの動作

現在のディレクトリを削除するときのbashの動作

を使用していますGNU bash, version 4.3.42(1)-release (x86_64-redhat-linux-gnu)

仮想ディレクトリを作成してhelloそこに移動しました。中に入ると、/tmp/helloディレクトリ自体を削除しました。

$ pwd
/tmp/hello
$ rmdir $PWD

確認しましたが、まだそのディレクトリにあります。

$ pwd
/tmp/hello

その後、ディレクトリ自体に移動しようとしましたが、もちろん不可能でした(すでにディレクトリにあったにもかかわらず)。

$ cd $PWD
bash: cd: /tmp/hello: No such file or directory

ところで、cd .これはcd $PWD何とか動作します。

$ cd .
cd: error retrieving current directory: getcwd: cannot access parent directories: No such file or directory

驚いたことに、私は今新しい「物事」に陥っています。

$ pwd
/tmp/hello/.

もちろん、以前のディレクトリに移動しようとすると失敗します。

$ cd -
bash: cd: /tmp/hello: No such file or directory

興味深いことにman、1ページしか機能しません。

$ man cd
man: can't change directory to '': No such file or directory
man: command exited with status 255: (cd  && LESS=-ix8RmPm Manual page cd(1) ?ltline %lt?L/%L.:byte %bB?s/%s..?e (END):?pB %pB\%.. (press h for help or q to quit)$PM Manual page cd(1) ?ltline %lt?L/%L.:byte %bB?s/%s..?e (END):?pB %pB\%.. (press h for help or q to quit)$ MAN_PN=cd(1) less -s)

なぜこれが起こるのですか?

答え1

@BinaryZebraに同意します。この質問は、以前に要求されたことがあることを指摘するのは公平です(例:コマンドラインインターフェイスを使用して内部からディレクトリを削除する[コピー]、参照できます。無期限)、観察可能な特性は周知である。

POSIX関連の動作の説明は、POSIX関連の動作に関する情報を提供できるため、より興味深いものです。予想されるアクション。関連するPOSIX文書は次のとおりです。

内部にアプリケーションの使い方CD部分は注目に値する。

cdは現在のシェル実行環境に影響を与えるため、常に通常のシェル組み込みコマンドとして使用できます。

内部に説明するセクションCDの項目10は、最も関連性の高い情報を提供する。

  1. その後、cdユーティリティは次の操作を実行する必要があります。chdir()通話機能コパスパスパラメータとして。何らかの理由でこれらの操作が失敗した場合、cdユーティリティはそのエラーメッセージを表示し、この手順の残りの部分を実行しません。この-Pオプションが無効な場合は、PWDステップ9に入ったとき(つまり、相対パス名に変換する前に)環境変数をcurpath値に設定する必要があります。この-Pオプションが適用される場合、PWD環境変数は出力される文字列に設定する必要がありますpwd -P。新しいディレクトリまたはこのディレクトリの親ディレクトリに現在の作業ディレクトリを決定するのに十分な権限がない場合、PWD環境変数の値は指定されません。

つまりPWD出力コマンドcdではなく入力するだからだいたい無視されるコマンドとしてcd。 「未指定」の最後の説明を参照してください。 POSIXは、$PWD呼び出しが失敗した場合に何が起こるかを明らかにするchdir()ことを拒否しました。

議論中環境変数の場合、pwdPOSIX コメントは次のとおりですPWD

現在の作業ディレクトリの絶対パス名。アプリケーションが値を設定または設定解除すると、PWD動作はpwd指定されません。

つまり、POSIXは、コマンドを正常に使用すること(成功した呼び出しと一致する)$PWD以外のコマンドを設定できる他の方法を指定することを拒否します。cdchdir()

どちらの文書もパスが「キャッシュされている」ことを意味すると解釈できるフレーズはなく、単に作業ディレクトリが存在することを意味します(おそらく)内部シェル実行環境。ディスカッション自体は、cdディレクトリが名前なしで存在し続ける可能性については言及していません。ドキュメント自体もcd存在しないディレクトリについては気にしません。これは説明で行われる。chdir()機能は失敗の多くの原因の1つです。例えば

[ENOENT]
~の一部既存のディレクトリの名前を指定しないでください。空の文字列です。

説明にはchdir()特別な処理に関する言及はありません。"."それはおそらく、POSIXは次のように絶対パス名を計算するプロセスを詳しく説明していないからです。getcwd()たとえば、"."およびなしのファイルシステムを許可します".."。これが実際に真であれば、誰かが実装が機能していないと見なすことができることchdir(".")を指摘するためにフレーズを追加できます。

ステップ10に戻ると、次のように明確に説明されます。

何らかの理由でこれらの操作が失敗した場合、cdユーティリティは適切なエラーメッセージを表示し、この手順の残りの部分を実行しません。

アップデートPWD完了後ろにその文章だから変える可能性はないそれ失敗時の値。

後ろに、このオプションpwdについて話します。-L

PWD環境変数に現在のディレクトリへの絶対パス名が含まれており、ファイル名のドットまたはドットポイントが含まれていない場合は、pwdこのパス名を標準出力に書き込む必要があります。

それから

両方が指定されていない場合、-Lユーティリティは指定されたように機能し-Pます。pwd-L

したがって、一連の仮定された動作がありますが、シェルの明示的な説明はありません。使用変数PWD自体は作業ディレクトリのコンテナとして機能します。代わりに、次のようになります。指定されていないこれにより、一部のPOSIX互換アプリケーションは、「仮想動作」ポイントを満たす限り、データを構成する別の方法を選択できます。

答え2

POSIX文書の説明に対する個人的な解釈を繰り返すことはOPには役立ちません。 POSIXを詳しく説明するいくつかの他の質問があります。ところで、この質問。


いくつかの基本的な説明:
。 Linux / Unixのよく知られている特徴は、使用中にファイル(ディレクトリ)が削除される可能性があることです。そのため、映画を削除しても視聴できます。ファイルはディレクトリエントリのinodeが削除されたときにのみ消えます。

第二。環境変数$ PWDの値が変更されても、シェルは実際のpwdの内部値を保持します。

@yaegashiが受け入れた答えに対する最初のコメントは、どこを見るべきかを示しています(pwdソース)。

私は正しいです。バラより由来pwd_builtin()。ただthe_current_working_directoryの内容を印刷します。 – 八重ヶ市 7月31日 16:01

示されているように、PWDに奇数の値で始まっても、シェルはまだpwd( "/home / user")の正しい値を知っています。

。一部の特殊なケースでは、シェルに格納されている値が実際と同期しない可能性があることを簡単に理解できます。

削除されたディレクトリで作業することは、cd .これらの特殊なケースの1つのようです。シェルは、失敗時に最後に知られたパスワードにドットを追加するようです。


あなたの問題:

1。 PWDディレクトリを削除し、組み込みpwdを実行します。

$ pwd
/tmp/hello
$ rmdir $PWD;   pwd
/tmp/hello

pwd組み込み機能は、シェルがメモリに保持しているpwd値を報告します。失敗は
外部的に報告されます/bin/pwd
興味深いことに、報告pwd -P(Bashの組み込み機能も含む)は失敗を報告します。

$ pwd -P
pwd: error retrieving current directory: getcwd: cannot access parent directories: No such file or directory

また、pwd -P組み込みコマンドを使用した後、通常のpwdは失敗します。メモリのpwd値が更新されたからだと思います。

2.CD $PWD

その後、ディレクトリ自体に移動しようとしましたが、もちろん不可能でした(すでにディレクトリにあったにもかかわらず)。

   $ cd $PWD
   bash: cd: /tmp/hello: No such file or directory

ディレクトリが読み取れない場合(ディレクトリが存在しない場合)、ディレクトリパスに従う試みは失敗します。

三。CD。

cd .しかし、同じでなければならないので、cd $ PWDを使ってみました。これは何とか動作します。

   $ cd .
   cd: error retrieving current directory: getcwd: cannot access parent directories: No such file or directory

シェルは既知のpwdパスにアクセスしようとしますが、失敗します。シェルが報告する内容は次のとおりです。 FAILED!ここに問題はありません。

4.新しい道。

驚いたことに、私は今新しい「物事」に陥っています。

$ pwd
/tmp/hello/.

PWDメモリの値が実際の状況と一致しないため、ドット(.)が追加されます。再利用するとcd .ポイントが追加されるからです。

$ cd .; pwd
/tmp/hello/./.

そして予期せず、aはcd ..pwdと$ PWDのみを生成します..

$ cd ..; pwd; echo $PWD
..
..
$ cd ..; pwd; echo $PWD
../..
../..

5.元障害者。

もちろん、以前のディレクトリに移動しようとすると失敗します。

$ cd -
bash: cd: /tmp/hello: No such file or directory

これは、PWDの以前の値(OLDPWDのbashに格納されている)を尊重できないために発生します。
これは(上記で報告したように)/tmp/hello/.(helloで削除されます)従うことはできず、成功またはcd -失敗cd $OLDPWDします。

$ echo $OLDPWD                 # at this point following your exact procedure.
/tmp/hello/.

6.マニュアルページ

興味深いことに、マニュアルページも機能しません。

この時点で、マニュアルページは実際にはすべての点で私にうまく機能します。

答え3

POSIX現在のディレクトリパスをキャッシュする必要があり、削除されたディレクトリはまだ存在しますが名前はありません。

cd .明らかに、その文字列を現在キャッシュされている名前に追加するようです。

関連情報