我有时会在一台机器上注意到这种行为(使用 Mate 终端的 Ubuntu)。
情况1
我在同一路径上打开了 2 个终端。我对它们都执行了“ls”,但其中一个的输出不正确,某些文件丢失,好像它指向该目录的较旧状态。
案例 2
我对该目录中的文件进行 cat 操作,第一次在其相对路径上,第二次在其绝对路径上,输出不同,其中一种情况是旧内容。
除此之外,终端表面上表现正常。如果我重新打开行为不正常的终端,它就会消失,但它仍然很烦人,因为我可能会无意中发现自己处于不正确的文件系统状态,就好像它有时从未同步的缓存中读取文件系统数据一样。我无法将此与我正在执行的任何特定操作联系起来。
答案1
假设
某人或某物移动(重命名)目录。
解释
当移动(重命名)目录并创建新目录时,可能会发生您所描述的情况。考虑以下场景:
在一个 shell 中创建一个目录,进入它,创建几个常规文件,检查它们,查看您所在的位置:
# shell 1 mkdir /tmp/dirA && cd /tmp/dirA && echo foo >file1 && echo bar >file2 && touch file3 && ls -i && pwd -L && pwd -P && echo Success.
输出将会像这样:
335212 file1 335213 file2 335214 file3 /tmp/dirA /tmp/dirA Success.
此壳位于
/tmp/dirA
。从另一个 shell 移开
dirA
,创建一个新的dirA
,进入它,创建几个目录条目,检查它们,看看你在哪里:# shell 2 mv /tmp/dirA /tmp/dirA.old && mkdir /tmp/dirA && cd /tmp/dirA && cp -l ../dirA.old/file1 ./ && echo baz >file2 && ls -i && pwd -L && pwd -P && echo Success.
输出将会像这样:
335212 file1 335219 file2 /tmp/dirA /tmp/dirA Success.
此壳亦在
/tmp/dirA
。
两个 shell 都看到file1
相同的 inode 编号。它们看到file2
不同的 inode 编号(和不同的内容)。第一个 shell 看到file3
,第二个 shell 看不到。
ls -id . /tmp/dirA /tmp/dirA.old
也可在两个 shell 中运行。
事实是第一个 shell 位于现在的目录中dirA.old
,但是shell 没有意识到名称已经改变:
# shell 1
ls -i &&
pwd -L &&
pwd -P &&
echo Success.
pwd
是 Bash 的内置命令,输出将如下所示:
335212 file1 335213 file2 335214 file3
/tmp/dirA
/tmp/dirA
Success.
但pwd
可执行文件还会告诉你一些其他的事情:
# shell 1
/bin/pwd -P
它会告诉你/tmp/dirA.old
!此外:
# shell 1
cat ./file2
cat /tmp/dirA/file2
bar
将从baz
两个不同的文件中打印。
“使固定”
dirA.old
你可以通过cd
-ing 命令让第一个 shell 确认它已经存在/bin/pwd -P
:# shell 1 cd "$(/bin/pwd -P)"
Xor 你可以
cd
到当前dirA
:# shell 1 cd .
虽然
cd .
这里看起来像是一个无操作,但它实际上会改变目录。
请注意,如果当前目录再次重命名,那么混乱将再次开始。
解决方案
识别谁或什么重命名了目录,使其停止;或者不要在即将重命名且重复使用旧名称的目录中工作。
或者也许改变一些工作流程就足够了。例如,如果有一个备份脚本移动一些源目录并通过复制回来重新创建源,请考虑从源复制到目标,而根本不修改源目录。