web-dev-qa-db-ja.com

現在のディレクトリが削除されるとどうなりますか?

最初の端末Aで、ディレクトリを作成し、ディレクトリを入力して、ファイルを作成します。

$ mkdir test
$ cd test
$ touch file1.txt
$ ls
file1.txt

次に、別の端末Bで、ディレクトリを削除します。

$ rm -r test
$ mkdir test
$ cd test
$ touch file2.txt

そして再びターミナルAに戻って(cdを実行していません)、ファイルをリストしようとします:

$ ls

lsは何も表示せず、文句もありません。

バックグラウンドで何が起こりますか? lsが問題を認識しないのはなぜですか?そして、ターミナルAで何かが正しくないことを見つけるための標準的な、ポータブルな、および/または推奨される方法はありますか?

pwdは、一見正しいディレクトリ名を出力するだけです。 touch file3.txtは、役に立たないそのようなファイルやディレクトリはないと言っています。 bash -c "pwd"だけが2つの長いエラー行を表示します。これは、何かが間違っていることを何らかの形で示しますが、実際には説明的ではなく、異なるシステム間でどれほど移植性があるかわかりません(Ubuntu 16.04を使用しています)。 cd .. && cd testは問題を修正しますが、実際には何が起こったのかを説明していません。

3
wenzeslaus

lsが問題を認識しないのはなぜですか?

そもそも「問題」はありません。

ターミナルAに何かが正しくありません

正しくないことは何もありません。リンクされていないファイルが開いているプロセスのセマンティクスが定義されているのと同じように、リンクされていないディレクトリが開いているプロセスのセマンティクスが定義されています。どちらも正常なものです。

何かを参照しているディレクトリエントリのリンクを解除し(その何かをどこかで開いている間)、何か他のものにリンクする元の名前でディレクトリエントリを作成するための定義されたセマンティクスがあります:あなたこれらのものが2つあり、最初のオープンディスクリプションを参照しても2番目のディスクリプションにアクセスできません。その逆も同様です。これは、ファイルの場合と同様にディレクトリにも当てはまります。

プロセスは、次のようにディレクトリのオープンファイルの説明を持つことができます。

  • プロセスの作業ディレクトリです。
  • プロセスのルートディレクトリです。
  • opendir()ライブラリ関数を呼び出したプロセスによって開かれています。または
  • open()ライブラリ関数を呼び出したプロセスによって開かれています。

rmdir()は、まだ開いているディレクトリへのリンクの削除に失敗することが許可されています(これは、一部の古いUnicesの動作であり、一部の非Unix非Linux POSIX準拠システムの動作です)。 まだ開いているディレクトリがパス名コンポーネントで終わる名前を介してリンク解除されている場合に失敗する必要があります_._;しかし、成功してディレクトリへの最後のリンクが削除された場合、定義されたセマンティクスは、まだ開いているがリンクされていないディレクトリです。

  • ディレクトリエントリがまったくない;
  • 試行中のプロセスに書き込みアクセスまたは特権アクセスがある場合でも、その後にディレクトリエントリを作成することはできません。

お使いのオペレーティングシステムは、このような状況でrmdir()からEBUSYを返さないものの1つであり、最初のターミナルセッションのシェルには、現在のディレクトリとしてリンクされていないが開いているディレクトリがあります。あなたが見たものはすべて、その状況で定義された行動でした。たとえば、lsは、twoディレクトリの空のまだ開いているfirstディレクトリを示しました。その点。

pwdの出力でさえありました。そのシェルで組み込みコマンドとして実行すると、シェルはシェル/環境変数の現在のディレクトリの名前を内部的に追跡していました。別のシェルで組み込みコマンドとして実行すると、別のシェルが、デバイスとその作業ディレクトリのiノード番号を2番目のディレクトリと一致しませんでした。継承したPWD環境変数の内容。したがって、PWDの内容を信頼しないことを決定し、thengetcwd() library function作業ディレクトリに名前がなくなったため、リンクが解除されました。

参考文献

4
JdeBP