最初の端末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
は問題を修正しますが、実際には何が起こったのかを説明していません。
ls
が問題を認識しないのはなぜですか?
そもそも「問題」はありません。
ターミナルAに何かが正しくありません
正しくないことは何もありません。リンクされていないファイルが開いているプロセスのセマンティクスが定義されているのと同じように、リンクされていないディレクトリが開いているプロセスのセマンティクスが定義されています。どちらも正常なものです。
何かを参照しているディレクトリエントリのリンクを解除し(その何かをどこかで開いている間)、何か他のものにリンクする元の名前でディレクトリエントリを作成するための定義されたセマンティクスがあります:あなたこれらのものが2つあり、最初のオープンディスクリプションを参照しても2番目のディスクリプションにアクセスできません。その逆も同様です。これは、ファイルの場合と同様にディレクトリにも当てはまります。
プロセスは、次のようにディレクトリのオープンファイルの説明を持つことができます。
opendir()
ライブラリ関数を呼び出したプロセスによって開かれています。またはopen()
ライブラリ関数を呼び出したプロセスによって開かれています。rmdir()
は、まだ開いているディレクトリへのリンクの削除に失敗することが許可されています(これは、一部の古いUnicesの動作であり、一部の非Unix非Linux POSIX準拠システムの動作です)。 まだ開いているディレクトリがパス名コンポーネントで終わる名前を介してリンク解除されている場合に失敗する必要があります_.
_;しかし、成功してディレクトリへの最後のリンクが削除された場合、定義されたセマンティクスは、まだ開いているがリンクされていないディレクトリです。
お使いのオペレーティングシステムは、このような状況でrmdir()
からEBUSY
を返さないものの1つであり、最初のターミナルセッションのシェルには、現在のディレクトリとしてリンクされていないが開いているディレクトリがあります。あなたが見たものはすべて、その状況で定義された行動でした。たとえば、ls
は、twoディレクトリの空のまだ開いているfirstディレクトリを示しました。その点。
pwd
の出力でさえありました。そのシェルで組み込みコマンドとして実行すると、シェルはシェル/環境変数の現在のディレクトリの名前を内部的に追跡していました。別のシェルで組み込みコマンドとして実行すると、別のシェルが、デバイスとその作業ディレクトリのiノード番号を2番目のディレクトリと一致しませんでした。継承したPWD
環境変数の内容。したがって、PWD
の内容を信頼しないことを決定し、thenはgetcwd()
library function作業ディレクトリに名前がなくなったため、リンクが解除されました。
rmdir()
。 「システムインターフェース」。 オープングループベース仕様。 IEEE 1003.1:2017。