我有两个弹壳。第一个位于目录A中。第二个删除目录A,然后重新创建它。当我回到第一个shell并输入时ls
,输出为:
ls: cannot open directory .: Stale file handle
为什么?我认为第一个外壳程序(在不存在的目录中保持打开状态的外壳程序)将在等待下一个命令时“冻结”,并且不会“意识到”该目录已被删除并重新创建。除了字符串以外,shell是否对它的当前工作目录保留“更深”的引用$PWD
?
我有两个弹壳。第一个位于目录A中。第二个删除目录A,然后重新创建它。当我回到第一个shell并输入时ls
,输出为:
ls: cannot open directory .: Stale file handle
为什么?我认为第一个外壳程序(在不存在的目录中保持打开状态的外壳程序)将在等待下一个命令时“冻结”,并且不会“意识到”该目录已被删除并重新创建。除了字符串以外,shell是否对它的当前工作目录保留“更深”的引用$PWD
?
Answers:
目录(如任何文件)不是由其名称定义的。将名称视为目录的地址。当您移动目录时,它仍然是同一目录,就像您移动到另一间房子一样,您仍然是同一个人。如果您删除一个目录并用相同的名称创建一个新目录,那么它就是一个新目录,就像搬进您以前居住的房子的人不是您一样。
每个进程都有一个工作目录。cd
外壳程序中的命令更改了外壳程序的当前工作目录。该pwd
命令将“¹”路径打印到当前工作目录。
当您删除目录A时,这样做是为了删除A在其父目录中的条目。目录A本身保留在文件系统中,但处于分离状态,没有名称。尚未删除它,因为某个进程(即第一个shell)正在使用它。当您在第一个外壳中更改目录时,该目录最终被删除。当在进程仍处于打开状态时删除文件时,也会发生同样的事情:文件的目录条目会立即被删除,而文件本身在停止使用时也会被删除。
同样,观察目录移动时会发生什么。
mkdir one two
touch one/1 two/2
cd one
ls
在另一个外壳中:
mv one tmp
mv two one
mv tmp two
在第一个外壳中:
ls
该文件1
位于最初调用的目录中,one
现在称为two
。该文件2
位于最初调用的目录中,two
现在称为one
。
¹ 更确切地说,一条路径,如果涉及符号链接或其他细微之处,则可能不是唯一的。
/proc/<pid>/cwd
,其工作方式类似于/proc/<pid>/fd/<number>
。这是CWD
在输出lsof
。
cd - && cd -
在这种情况下可以自动进行?
这是预期的行为。新目录A与旧目录A不同,只是名称相同。因此,第一个航站楼的$ PWD仍然不见了,当您执行时,它并没有神奇地重新出现mkdir A
。
目录(如文件)具有与之关联的索引节点:
307%mkdir ABC
308%ls -i 11997708 A 11997709 B 11997710 C
索引节点是一种数据结构,其中包含有关目录或文件的信息。每个目录和文件都有一个。将其视为地址(实际上是索引号)。
如果我在A中,索引节点号为11997708,并且在另一个外壳中(或将在相同的外壳中),则删除目录A,然后重新创建它并使索引节点ls:
309%CD A
均方根值310%../A
311%mkdir ../A
312%ls -i ..
11997720 A 11997709 B 11997710 C
i节点是不同的,因此如果它尝试在已删除的目录A中创建文件:
313%触摸此
touch:无法触摸“ this”:没有此类文件或目录
因为我所在的目录-不再与inode 11997720关联 -所以我当前所在的目录不再具有合法的地址/索引-inode。因此错误。
cd $PWD
。