如何删除这个不可删除的目录呢?

如何删除这个不可删除的目录呢?

我解压了一个损坏的 tar 文件,并设法得到了一些我无法删除的目录,如果我尝试删除它,似乎找不到它,但ls显示它存在,无论是使用 bash 还是使用 python 我都得到类似的行为,除了在我尝试使用 删除它之后rm -rfls抱怨它找不到它,然后它列出了它(见下文rm -rf)。该find命令显示该文件存在,但我仍然想不出删除它的方法。
这是我的尝试:

在这里您可以看到两者lsfind同意我们有一个目录,

rl]$ ls
mikeaâ??cnt
rl]$ find -maxdepth 1 -type d -empty -print0  
./mikeaâcnt 

但我无法删除它:

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

我可以cd,但它是空的:

rl]$ cd mikeaâ^Á^Äcnt/
mikeaâ^Á^Äcnt]$ ls
mikeaâ^Á^Äcnt]$ pwd
.../rl/mikeaâcnt


mikeaâ^Á^Äcnt]$ cd ../
rl]$ ls
mikeaâ??cnt

请看下面,这不是一个简单的文件,而是一个目录,而且在 它说找不到该文件然后直接列出它之后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]$ 

这是使用 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'

即使当我使用制表符补全时,它选择的名称也无法使用:

rl]$ rm -rf mikeaâ^Á^Äcnt 
rl]$ ls
ls: cannot access mikeaâcnt: No such file or directory
mikeaâ??cnt

使用 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

我能做些什么来摆脱这个损坏的目录吗?底层文件系统(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]$

但文件仍然在那里,(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

行为仍然不变,文件仍然存在

第三次编辑:

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

这个名字似乎比mikeaâcnt查看 python attempts 的输出 mikea\xc3\xa2\xc2\x81\xc2\x84cnt和这个屏幕截图更重要:

ls 输出

第四次编辑:这是使用通配符的尝试:

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

和我的语言环境:

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=

第五次编辑:

rl]$ ls -i 
ls: cannot access mikeaâcnt: No such file or directory
? mikeaâ??cnt

而且行为也发生了变化,现在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.

这是在尝试删除后发生的,我认为这可能是答案之一中建议的 NFS 问题这里由 vinc17 提供。

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

第七次编辑:移动不起作用,(我在这一切之前尝试过,但我没有保存输出),但它与文件有相同的ls问题rm

第八次编辑:这是按照建议使用十六进制字符:

 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]$

第九次编辑:对于stat命令:

 rl]$ stat  mikeaâ^Á^Äcnt 
stat: cannot stat `mikeaâ\302\201\302\204cnt': No such file or directory
 rl]$

从所有输出来看,更有可能存在评论中建议的错误或其他 NFS 不当行为。

编辑10:这是strace输出的要点,因为它太大了,它的输出或这两个命令:

strace -xx rmdir ./* | grep -e '-1 E'`
strace -xx -e trace=file ls -li`

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 ../

最终编辑:我看到一个本地管理员对此进行了处理,并通过登录到服务器本身并从那里删除来处理。他们的解释是,可能是名称中的字符集不合适的问题。

答案1

像这样删除文件/目录的一种方法是通过它们的索引节点引用。

要查找当前目录中元素的索引节点:

ls -i
14813568 mikeaâcnt

要删除此内容:

find . -inum 14813568 -delete

答案2

以下内容摘自这篇文章可能解释了为什么该目录拒绝被删除:

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 文件名。换句话说,虽然有些人认为 Linux 不会强制文件名使用特定的字符编码,但实际上在某些情况下它已经要求文件名使用 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,因此很容易出现垃圾。

答案3

您不应在命令行中使用非 ASCII 字符,因为如您所见,由于某种原因,它们不一定对应于文件名(Unicode 有多种方式来表达重音字母)。就像是:

rm -rf mike*

应该可以工作,因为文件名是由 shell 直接生成的。但请确保只有一个匹配项(echo mike*首先进行确认)。

好吧,如果cd有效,那么没有理由rmls应该说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

我怀疑该文件仍然存在于目录表由于 NFS 缓存和/或因为它被另一个进程使用,但没有关联信息。当ls尝试获取有关文件本身的信息时,它会收到错误,因为文件本身不再存在(它仅存在于目录表中),因此会显示错误。然后ls输出文件名,因为它位于目录表中。您在一种情况下有问号但在另一种情况下没有问号的事实是由于ls恕我直言的显示错误(与您的问题无关)。

答案4

我相信我也遇到过同样的问题。我之前已经看到过文件名为.ls在这种情况下,文件显示为â??,但我可以使用 删除它rm ☃

这导致我采用以下方法将错误的名称转换为正确的名称:

首先获取文件名的字节:

$ ls --show-control-chars | xxd
0000000: 6d69 6b65 61c3 a2c2 81c2 8463 6e74 0a    mikea......cnt.

然后将这些字节解码为 UTF-8,以获取 unicode 代码点,使用此网站的十六进制输入例如:http://software.hixie.ch/utilities/cgi/unicode-decoder/utf8-decoder

U+006D LATIN SMALL LETTER M character
U+0069 LATIN SMALL LETTER I character
U+006B LATIN SMALL LETTER K character
U+0065 LATIN SMALL LETTER E character
U+0061 LATIN SMALL LETTER A character
U+00E2 LATIN SMALL LETTER A WITH CIRCUMFLEX character (&#x00E2;)
U+0081 <control> character (&#x0081;)
U+0084 <control> character (&#x0084;)
U+0063 LATIN SMALL LETTER C character
U+006E LATIN SMALL LETTER N character
U+0074 LATIN SMALL LETTER T character

请注意,这些都低于字节边界。我们得到以下字节:

6D 69 6B 65 61 E2 81 84 63 6E 74

如果我们以 UTF-8 处理该序列,我们会得到:

U+006D LATIN SMALL LETTER M character
U+0069 LATIN SMALL LETTER I character
U+006B LATIN SMALL LETTER K character
U+0065 LATIN SMALL LETTER E character
U+0061 LATIN SMALL LETTER A character
U+2044 FRACTION SLASH character (&#x2044;)
U+0063 LATIN SMALL LETTER C character
U+006E LATIN SMALL LETTER N character
U+0074 LATIN SMALL LETTER T character

因此你的文件名是:mikea⁄cnt,带有分数斜杠而不是普通的正斜杠。您现在可以将此名称传递给rmdir.

相关内容