fon*_*ini 13 filesystems bash open-files pwd
我打开了两个贝壳。第一个在目录 A 中。在第二个中,我删除目录 A,然后重新创建它。当我回到第一个 shell 并键入 时ls,输出为:
ls: cannot open directory .: Stale file handle
Run Code Online (Sandbox Code Playgroud)
为什么?我认为第一个 shell(在不存在的目录中保持打开状态的 shell)会在等待下一个命令时“冻结”,并且不会“意识到”该目录已被删除并重新创建。除了字符串之外,shell 是否持有对其当前工作目录的“更深层次”引用$PWD?
Gil*_*il' 17
目录(如任何文件)不是由其名称定义的。将名称视为目录的地址。当你移动目录时,它仍然是同一个目录,就像你搬到不同的房子,你仍然是同一个人。如果你删除一个目录并创建一个同名的新目录,它就是一个新目录,就像搬进你以前住的房子的人不是你一样。
每个进程都有一个工作目录。cdshell 中的命令会更改 shell 的当前工作目录。该pwd命令打印当前工作目录的¹路径。
当您删除目录 A 时,这样做是删除其父目录中 A 的条目。目录 A 本身保留在文件系统中,但处于分离状态,没有名称。它还没有被删除,因为它正在被一个进程使用,即第一个 shell。当您在第一个 shell 中更改目录时,该目录最终被删除。当一个文件被删除而进程仍然打开它时,同样的事情会发生:文件的目录条目被立即删除,并且文件本身在它停止使用时被删除。
同样,观察移动目录时会发生什么。
mkdir one two
touch one/1 two/2
cd one
ls
Run Code Online (Sandbox Code Playgroud)
在另一个外壳中:
mv one tmp
mv two one
mv tmp two
Run Code Online (Sandbox Code Playgroud)
在第一个外壳中:
ls
Run Code Online (Sandbox Code Playgroud)
该文件1位于最初调用one和现在调用的目录中two。该文件2位于最初调用two和现在调用的目录中one。
¹更准确地说,是一条路径,如果涉及符号链接或其他微妙之处,则该路径可能不是唯一的。
新目录A与目录A不同,stat删除旧目录前和新建目录后用命令查看,会看到不同的i-node编号。
我认为这与内核的工作方式有关。它只是跟踪每个进程的当前目录的 i-number。因此,由于有不同的 i 编号,这将导致不同的冲突。
这是预期的行为。新目录 A 与旧目录 A 不同,它恰好具有相同的名称。所以第一个终端的 $PWD 仍然消失了,当你执行mkdir A.