在第一个终端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"
给出了两条很长的错误行,这在某种程度上揭示了某些问题,但并不是真正的描述性,我不确定它在不同系统之间的可移植性如何(我使用的是 Ubuntu 16.04)。cd .. && cd test
解决了问题,但没有真正解释发生了什么。
答案1
怎么
ls
看不出问题来呢?
首先不存在“问题”。
A 航站楼有些不对劲
没有什么不对的。对于打开未链接目录的进程有定义的语义,就像对于打开未链接文件的进程有定义的语义一样。两者都是正常的事情。
有定义的语义用于取消链接引用某些内容的目录条目(同时在某处打开该内容),然后通过链接到的原始名称创建目录条目别的东西: 你现在有两个那些东西的,并且引用第一个的开放描述不会访问第二个,反之亦然。对于目录和文件来说都是如此。
进程可以通过以下方式拥有目录的打开文件描述:
- 它是进程的工作目录;
- 它是进程的根目录;
- 它被调用库函数的进程打开
opendir()
;或者 - 它由调用库函数的进程打开
open()
。
rmdir()
允许无法删除指向仍然打开的目录的链接(这是某些旧 Unices 的行为,也是某些非 Unix-非 Linux POSIX 兼容系统的行为),并且必需的如果通过以路径名组件结尾的名称取消链接仍然打开的目录,则会失败.
;但如果成功并删除了目录的最终链接,则定义的语义是仍然打开但未链接的目录:
- 没有目录条目根本不;
- 此后无法创建任何目录条目,即使尝试进程具有写访问权限或特权访问权限。
EBUSY
您的操作系统是在这些情况下不会返回的操作系统之一rmdir()
,并且第一个终端会话中的 shell 有一个未链接但仍打开的目录作为其当前目录。你看到的一切都是在那种情况下定义的行为。 ls
,例如,显示空的仍然打开第一的目录, 的二您当时拥有的目录。
甚至是 was 的输出pwd
。当在该 shell 中作为内置命令运行时,该 shell 在内部跟踪 shell/环境变量中当前目录的名称。当在另一个 shell 中作为内置命令运行时,另一个 shell 无法将其工作目录的设备和索引节点号与第二个目录现在由它继承的环境变量的内容命名PWD
,因此决定不信任 的内容PWD
,并且然后库函数失败getcwd()
,因为工作目录没有任何名称不再有任何联系。
进一步阅读
rmdir()
。 “系统接口”。 The Open Group 基本规格。 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