mik*_*e-m 40 directory nfs rm files
我解压了一个损坏的 tar 文件,并设法得到了一些我无法删除的目录,如果我尝试删除它,似乎找不到ls
它,但显示它存在,无论是使用 bash 还是使用 python 我得到类似的行为,除了在我尝试用 删除它之后rm -rf
, ls
抱怨它找不到它,然后它列出它(见下文rm -rf
)。该find
命令显示文件存在,但我仍然想不出删除它的方法。
这是我的尝试:
在这里你看到了两者ls
并find
同意我们有一个目录,
rl]$ ls
mikeaâ??cnt
rl]$ find -maxdepth 1 -type d -empty -print0
./mikeaâcnt
Run Code Online (Sandbox Code Playgroud)
但我无法删除它:
rl]$ find -maxdepth 1 -type d -empty -print0 | xargs -0 rm -f -v
rm: cannot remove `./mikeaâ\302\201\302\204cnt': Is a directory
rl]$ ls
mikeaâ??cnt
Run Code Online (Sandbox Code Playgroud)
我可以cd
,但它是空的:
rl]$ cd mikeaâ^Á^Äcnt/
mikeaâ^Á^Äcnt]$ ls
mikeaâ^Á^Äcnt]$ pwd
.../rl/mikeaâcnt
mikeaâ^Á^Äcnt]$ cd ../
rl]$ ls
mikeaâ??cnt
Run Code Online (Sandbox Code Playgroud)
见下文,这不是一个简单的文件,而是一个目录,加上ls
在rm -rf
它说找不到文件然后直接列出它之后的行为很有趣:
rl]$ rm mikeaâ^Á^Äcnt/
rm: cannot remove `mikeaâ\302\201\302\204cnt/': Is a directory
rl]$ rm -rf mikeaâ^Á^Äcnt/
rl]$ ls
ls: cannot access mikeaâcnt: No such file or directory
mikeaâ??cnt
rl]$
Run Code Online (Sandbox Code Playgroud)
所以这是用python的尝试,找到了文件,但是名称不能用作可以删除的名称:
rl]$ python
Python 2.6.6 (r266:84292, Jul 10 2013, 22:48:45)
[GCC 4.4.7 20120313 (Red Hat 4.4.7-3)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> import shutil
>>> os.listdir('.')
['mikea\xc3\xa2\xc2\x81\xc2\x84cnt']
>>> shutil.rmtree(os.listdir('.')[0] )
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib64/python2.6/shutil.py", line 204, in rmtree
onerror(os.listdir, path, sys.exc_info())
File "/usr/lib64/python2.6/shutil.py", line 202, in rmtree
names = os.listdir(path)
OSError: [Errno 2] No such file or directory: 'mikea\xc3\xa2\xc2\x81\xc2\x84cnt'
Run Code Online (Sandbox Code Playgroud)
即使我使用制表符补全,它选取的名称也不可用:
rl]$ rm -rf mikeaâ^Á^Äcnt
rl]$ ls
ls: cannot access mikeaâcnt: No such file or directory
mikeaâ??cnt
Run Code Online (Sandbox Code Playgroud)
使用 python 用 bash 显示的名称,我得到了这个:
rl]$ rm -rf "mikea\xc3\xa2\xc2\x81\xc2\x84cnt"
rl]$ ls
ls: cannot access mikeaâcnt: No such file or directory
mikeaâ??cnt
Run Code Online (Sandbox Code Playgroud)
我能做些什么来摆脱这个损坏的目录吗?底层文件系统 (NFS) 似乎可以正常运行,并且没有报告其他问题,并且在损坏的 tar 文件之前我没有遇到过这样的问题。
编辑:这是使用find
自己的-exec
选项来调用rm
rl]$ find -maxdepth 1 -type d -empty -exec rm -f {} \;
find: `./mikeaâ\302\201\302\204cnt': No such file or directory
rl]$ ls
ls: cannot access mikeaâcnt: No such file or directory
mikeaâ??cnt
rl]$
Run Code Online (Sandbox Code Playgroud)
但文件仍然存在,(ls
抱怨它找不到它,但无论如何还是显示了它)
第二次编辑:
rl]$ find -maxdepth 1 -type d -empty -exec rm -rf {} \;
find: `./mikeaâ\302\201\302\204cnt': No such file or directory
rl]$ ls
ls: cannot access mikeaâcnt: No such file or directory
mikeaâ??cnt
Run Code Online (Sandbox Code Playgroud)
行为仍然不变,文件仍然存在
第三次编辑:
rl]$ ls
mikeaâ??cnt
rl]$ find -maxdepth 1 -type d -empty -exec rm -rf {} +
rl]$ ls
ls: cannot access mikeaâcnt: No such file or directory
mikeaâ??cnt
Run Code Online (Sandbox Code Playgroud)
除了mikeaâcnt
查看 python 尝试的输出 之外,这个名称似乎还有更多内容mikea\xc3\xa2\xc2\x81\xc2\x84cnt
,还有这个截图:
第 4 次编辑:这是使用通配符的尝试:
rl]$ echo *
mikeaâcnt
rl]$ echo mike*
mikeaâcnt
rl]$ rm -rf mike*
rl]$ ls
ls: cannot access mikeaâcnt: No such file or directory
mikeaâ??cnt
Run Code Online (Sandbox Code Playgroud)
和我的语言环境:
rl]$ locale
LANG=en_US.utf8
LC_CTYPE="en_US.utf8"
LC_NUMERIC="en_US.utf8"
LC_TIME="en_US.utf8"
LC_COLLATE="en_US.utf8"
LC_MONETARY="en_US.utf8"
LC_MESSAGES="en_US.utf8"
LC_PAPER="en_US.utf8"
LC_NAME="en_US.utf8"
LC_ADDRESS="en_US.utf8"
LC_TELEPHONE="en_US.utf8"
LC_MEASUREMENT="en_US.utf8"
LC_IDENTIFICATION="en_US.utf8"
LC_ALL=
Run Code Online (Sandbox Code Playgroud)
第 5 次编辑:
rl]$ ls -i
ls: cannot access mikeaâcnt: No such file or directory
? mikeaâ??cnt
Run Code Online (Sandbox Code Playgroud)
而且行为发生了变化,现在ls
和cd
这样做:
rl]$ ls
ls: cannot access mikeaâcnt: No such file or directory
mikeaâ??cnt
rl]$ cd mikeaâ^Á^Äcnt
mikeaâcnt: No such file or directory.
Run Code Online (Sandbox Code Playgroud)
这发生在尝试删除之后,我认为这可能是vinc17此处的其中一个答案中所建议的 NFS 问题。
6日编辑:这是的输出lsof
和ls -a
rl]$ /usr/sbin/lsof mikeaâ^Á^Äcnt lsof:mikeaâ\xc2\x81\xc2\x84cnt 上的状态错误:没有这样的文件或目录
上面是错误的,这里是正确的lsof
调用:(rl 是父目录)
rl]$ /usr/sbin/lsof | grep mike | grep rl
tcsh 11926 mike cwd DIR 0,33 4096 19569249 /home/mike/mish/rl
lsof 14733 mike cwd DIR 0,33 4096 19569249 /home/mike/mish/rl
grep 14734 mike cwd DIR 0,33 4096 19569249 /home/mike/mish/rl
grep 14735 mike cwd DIR 0,33 4096 19569249 /home/mike/mish/rl
lsof 14736 mike cwd DIR 0,33 4096 19569249 /home/mike/mish/rl
rl]$
rl]$ ls -a
ls: cannot access mikeaâcnt: No such file or directory
. .. mikeaâ??cnt
Run Code Online (Sandbox Code Playgroud)
7日编辑:此举将不工作,(我以前试过这一切,但我没有保存输出),但它有同样的问题ls
,并rm
与该文件。
第 8 次编辑:这是按照建议使用十六进制字符:
rl]$ ls --show-control-chars | xxd
0000000: 6d69 6b65 61c3 a2c2 81c2 8463 6e74 0a mikea......cnt.
rl]$ rmdir $'mikea\6d69\6b65\61c3\a2c2\81c2\8463\6e74\0acnt'
rmdir: failed to remove `mikea\006d69\006b651c3\a2c2\\81c2\\8463\006e74': No such file or directory
rl]$ ls
ls: cannot access mikeaâcnt: No such file or directory
mikeaâ??cnt
rl]$
Run Code Online (Sandbox Code Playgroud)
第 9 次编辑:对于stat
命令:
rl]$ stat mikeaâ^Á^Äcnt
stat: cannot stat `mikeaâ\302\201\302\204cnt': No such file or directory
rl]$
Run Code Online (Sandbox Code Playgroud)
从所有输出来看,它似乎更有可能,如评论中所建议的那样,存在错误或其他 NFS 不当行为。
编辑 10:这是 gist 中的 strace 输出,因为它太大了,它的输出或这两个命令:
strace -xx rmdir ./* | grep -e '-1 E'`
strace -xx -e trace=file ls -li`
Run Code Online (Sandbox Code Playgroud)
https://gist.github.com/mikeatm/e07fa600747a4285e460
编辑11:所以在上面 rmdir
我注意到我可以cd
进入目录,但之后rmdir
我不能cd
再次,类似于昨天。在.
和..
文件存在:
rl]$ ls
mikeaâ??cnt
rl]$ cd mikeaâ^Á^Äcnt/
mikeaâ^Á^Äcnt]$ ls
mikeaâ^Á^Äcnt]$ ls -a
. ..
mikeaâ^Á^Äcnt]$ cd ../
Run Code Online (Sandbox Code Playgroud)
最终编辑:我看到了一个本地管理员,它是通过登录到服务器本身并从那里删除来处理的。他们的解释是名称中的字符集不合适可能是一个问题。
小智 19
像这样删除文件/目录的一种方法是通过它们的 inode 引用。
要查找当前目录中元素的 inode:
ls -i
14813568 mikeaâcnt
Run Code Online (Sandbox Code Playgroud)
要删除它:
find . -inum 14813568 -delete
Run Code Online (Sandbox Code Playgroud)
Tim*_*tin 11
这篇文章的以下摘录可能解释了为什么该目录拒绝删除:
NFSv4 要求使用 UTF-8 通过网络交换所有文件名。NFSv4 规范 RFC 3530 说,文件名应该在 1.4.3 节中使用 UTF-8 编码:“稍微偏离,文件和目录名称使用 UTF-8 编码以处理国际化的基础知识。” 在较新的 NFS 4.1 RFC (RFC 5661) 部分 1.7.3 中也可以找到相同的文本。当前的 Linux NFS 客户端只是直接传递文件名,无需在当前语言环境和 UTF-8 之间进行任何转换。在使用远程 NFSv4 系统的系统上,使用非 UTF-8 文件名可能是一个真正的问题;任何遵循 NFS 规范的 NFS 服务器都应该拒绝非 UTF-8 文件名。因此,如果您想确保您的文件实际上可以从 Linux 客户端存储到 NFS 服务器,您目前必须使用 UTF-8 文件名。换句话说,
UTF-8 是一种长期方法。系统必须支持 UTF-8 以及许多较旧的编码,让人们有时间切换到 UTF-8。要使用“UTF-8 无处不在”,所有工具都需要更新以支持 UTF-8。多年前,这是一个大问题,但截至 2011 年,这基本上是一个已解决的问题,我认为对于那些少数尾随系统而言,轨迹非常清晰。
并非所有字节序列都是合法的 UTF-8,而且您不想弄清楚如何显示它们。如果内核强制执行这些限制,确保只允许使用 UTF-8 文件名,那么没问题……所有文件名都将是合法的 UTF-8。Markus Kuhn 的 utf8_check C 函数可以快速确定一个序列是否是有效的 UTF-8。
文件系统应该要求文件名符合某种标准,不是因为某些邪恶的需要控制人们,而只是为了以后总能正确显示名称。缺乏标准使用户的事情变得更难,而不是更容易。然而文件系统并不强制文件名是 UTF-8,所以它很容易产生垃圾。
您不应该在命令行中使用非 ASCII 字符,因为正如您所看到的,出于某种原因,它们不一定对应于文件名(Unicode 有多种表示重音字母的方法)。就像是:
rm -rf mike*
Run Code Online (Sandbox Code Playgroud)
应该可以工作,因为文件名是由 shell 直接生成的。但请确保只有一个匹配项(echo mike*
先进行确认)。
好吧,如果cd
有效,那么就没有理由rm
或ls
应该说No such file or directory
,因此问题可能出在文件系统级别。
注意:不要ls
用于查找目录是否为空,而是使用ls -a
.
该目录可能仍被另一个进程使用(包括它是否是某个进程的 cwd)。恕我直言,这就是为什么它仍然“存在”但会产生错误,例如使用ls
; lsof
可能会给您一些信息,但是对于 NFS,您需要找到使用它的机器。特别是对于 NFS,这可能会产生奇怪的错误。ls -a
在.nfs*
某些情况下,父目录中可能会显示文件/目录。
当你拿到时:
$ ls
ls: cannot access mikeaâcnt: No such file or directory
mikeaâ??cnt
Run Code Online (Sandbox Code Playgroud)
我怀疑由于 NFS 缓存和/或因为它被另一个进程使用,但没有相关信息,该文件仍然存在于目录表中。当ls
尝试获取有关文件本身的信息时,由于文件本身不再存在(仅在目录表中),因此会出现错误,因此显示错误。然后ls
输出文件名,因为它在目录表中。您在一种情况下有问号但在另一种情况下没有问号的事实是由于ls
恕我直言的显示错误(与您的问题无关)。
归档时间: |
|
查看次数: |
48361 次 |
最近记录: |