最初の端末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
そのファイルやディレクトリがないとは言いません。 2つの非常に長いエラー行だけをbash -c "pwd"
提供しますが、これは問題の内容をある程度明らかにしますが、実際には説明的ではなく、異なるシステム間でどのくらい移植性があるのかわかりません(私はUbuntu 16.04を使用しています)。cd .. && cd test
私は問題を解決しましたが、実際に何が起こっているのか説明しませんでした。
答え1
なぜ
ls
問題を見ることができないのですか?
そもそも「問題」はありません。
端末Aに問題が発生しました。
何の問題もありません。リンクされていないファイルを開くプロセスに定義された意味があるかのように、リンクされていないディレクトリを開くプロセスに対して定義された意味があります。どちらも正常なことです。
何かを参照するディレクトリエントリのリンクを解除し(そのコンテンツをどこかで開く間)、次のリンク元の名前でディレクトリエントリを生成するセマンティクスが定義されています。その他:あなた今は2つあります。最初の項目を参照する公開説明は2番目の項目にアクセスできず、その逆も同様です。これはディレクトリとファイルの両方に当てはまります。
プロセスは、次の方法でディレクトリの開かれたファイル記述を持つことができます。
- プロセスの作業ディレクトリです。
- プロセスのルートディレクトリです。
- ライブラリ関数を呼び出すプロセスによって開きます
opendir()
。 - これはライブラリ関数を呼び出すプロセスによって開きます
open()
。
rmdir()
まだ開いているディレクトリへのリンクを削除できないようにします(これはいくつかの以前のUnicesの動作であり、一部のUnix-non-Linux POSIX互換システムの動作でもあります)。必須まだ開いているディレクトリがパス名コンポーネントで終わる名前で接続を解除すると、失敗します.
。ただし、成功し、ディレクトリへの最終リンクが削除された場合、定義された意味はまだ開いているが接続されていないディレクトリに対するものです。
- ディレクトリエントリなし別の言葉;
- 試行しているプロセスに書き込みアクセスまたは特権アクセスがある場合でも、以降はディレクトリエントリを作成できません。
EBUSY
あなたのオペレーティングシステムはそのような場合に返されないオペレーティングシステムの1つでありrmdir()
、最初のターミナルセッションのシェルには接続されていませんが、まだ開いているディレクトリは現在ディレクトリにあります。あなたが見るすべては、その文脈で定義された行動です。 ls
たとえば、空白がまだ開いていることを示します。最初ディレクトリ二つ当時持っていたディレクトリ。
でも出力はpwd
。シェルから組み込みコマンドとして実行すると、シェルは内部的にシェル/環境変数の現在のディレクトリの名前を追跡します。別のシェルから組み込みコマンドとして実行すると、他のシェルは作業ディレクトリのデバイス番号とinode番号を比較できません。2番目のディレクトリこれで、継承した環境変数の内容によって名前が付けPWD
られるので、信頼できないものが決まりますPWD
。それからライブラリ機能が失敗しましたgetcwd()
。作業ディレクトリに名前がありません。もう連絡しないでください。
追加読書
rmdir()
。 「システムインターフェース」。 オープングループ基本仕様。 IEEE 1003.1:2017。- https://unix.stackexchange.com/a/413225/5132
- 「。」ディレクトリを削除できないのはなぜですか?
- 'rm .*'親ディレクトリを削除しましたか?
答え2
現在のディレクトリが削除されたことを確認したい場合は、inodeを確認してください。
まず、現在のディレクトリのinode番号(例:117002)を取得します。
ls -ial | grep '\s\.$' | awk '{print $1}'
次に、親ディレクトリでinodeパスを見つけます。それ以外の場合は、元のディレクトリが削除されます。
find .. -inum 117002