我正在尝试删除通过 PHP 脚本上传到我的服务器的 png 图像。每当我尝试通过 ftp 和终端删除它时,我都会收到错误
No such file or directory
但是,当我ls
进入目录时,会列出该文件,并且也会在我的 ftp 客户端中列出。我尝试创建一个同名文件,但最终得到了两个同名文件。
我可以打开据称不存在的文件,但仍然无法删除它。我也尝试过重启服务器。有什么想法可能是什么问题吗?我正在运行 64 位版本的 Ubuntu,但我不认为这是 32/64 位问题。我还应该注意,我已经删除了由同一 PHP 脚本上传的许多其他 png 文件。
输出ls -l
total 224
-rw-r--r-- 1 www-data www-data 222838 May 13 04:14 qyxdshyikfr_fishing_timeout.png
-rw-r--r-- 1 root root 272 May 14 06:54 upload.php
尝试时输出rm
rm: cannot remove ‘qyxdshyikfr_fishing_timeout.png’: No such file or directory
上传.php:http://pastebin.com/z87eypTY
答案1
我尝试创建一个同名的文件,但最终得到了两个同名的文件。
这就是说,如果没有文件系统损坏,你有两个文件有两个不同的名字那看起来一样因为非打印字符或字符集/字体中看起来相同的字符。在这种情况下,--escape
选项ls
是你的好朋友,工具如 也是cat -v
。
同样如此rm -i -- *
进一步阅读
答案2
总结:运行ls -1b
,找到文件名,复制它出现的行,然后将其提供给rm
。
ls
正如其他人所建议的,这很可能是由于某些程序(包括客户端和服务器软件)默认处理奇怪文件名(例如包含控制字符的文件名)的方式限制。您使用JdeBP 的回答强烈暗示情况确实如此,尽管在此之前这也是一个不错的选择。
对于
ls
,当标准输出是终端,?
字符会打印在它们的位置。因此,如果您没有将ls
的输出通过管道传输到任何其他命令(或将其重定向到日志以供查看),则您的文件名可能不包含控制字符。但还有其他有问题的字符——例如,文件名可能包含尾随空格。这种行为
ls
可能会令人困惑,但不是一个错误,可以由用户明确覆盖(见下文)。尝试远程访问或删除文件时,客户端中的错误或者服务器软件可能会产生此类问题。
ftp
我自己也经历过几次这样的事,包括名称包含尾随空格的文件。(它不起作用是由于我的 ftp 客户端中的一个错误。)即使您自己手动创建文件,根据您创建文件的方式,有时也很容易无意中插入尾随空格或其他看起来像空格但实际上不是空格的空格。
这是ls -1b
(或dir -1
)派上用场:
-1
指示ls
每行显示一个条目。这样就不会混淆一个文件名的结束位置和另一个文件名的开始位置。这对于名称奇怪的文件来说很方便。-b
告诉ls
打印任何特殊字符的转义序列。 的输出ls -b
可以复制并粘贴到命令中,无需添加引文:所有有问题的字符都已经以一种能让 shell 识别它们的方式引用了。
只有一个警告:如果一行中的最后一个字符似乎是\
,则复制其后的一个字符,因为这意味着\
引用一个空格。
您可以ls -1b
这样运行,也可以将 shell glob 模式传递给它(例如ls -1b qyx*
)。通配符可能会或可能不会找到该文件,这取决于控制字符(或其他奇怪的字符)是否存在于 glob 模式中出现的名称部分中。
复制了\
给出的带引号的文件名版本后ls
,您可以将其粘贴到命令中。您不必以任何方式手动修改它。如果您希望删除文件,请键入rm
,键入空格,粘贴该行,然后按Enter。
进一步阅读:
- 10.1
ls
:列出目录内容在里面GNU coreutils 参考手册。 - 我的答案到那个问题,这与您的问题非常不同,但主要涉及如何
ls
(和dir
)显示奇怪的文件名的问题。
答案3
所以我遇到了这个问题,这些方法都对我不起作用。有效的方法是创建一个名称完全相同的文件。它是一个名为 Example.1.2.3 的文件夹,所以我创建了一个新文件夹,并将其命名为与无法删除的文件夹完全相同的名称。旧文件夹消失了,我删除了新文件夹。
答案4
详细转载,扩展了我对 Eliah 的回答的评论
问题是看不见的,但如果你知道要查找什么,就可以看到:文件名末尾有一个空格。由于您复制/粘贴了整个ls
输出,因此如果您突出显示输出,或编辑帖子并将光标移到末尾,或者(如 Eliah 指出的那样)查看编辑历史记录中的差异,就可以在问题中看到它。我ls
在此屏幕截图中突出显示了帖子中的输出:
一个快速的小型终端会话来复制该问题,并带有注释:
$ touch 'foo ' # Create file with a space at the end
$ ls -l # Space is not visible in ls output
total 0
-rw-rw-r-- 1 izkata izkata 0 May 14 21:59 foo
$ rm foo # Cannot remove it when not specifying the space
rm: cannot remove ‘foo’: No such file or directory
$ rm 'foo ' # Can remove it if we quote the file name and include the space
$ rm foo\ # Or can escape the space to tell bash to include it as part of the filename
使用Tab 补全也可以完全避开这里的问题,因为 bash 足够智能,可以正确地转义空格(这通常也是一个好习惯,可以大大加快输入路径的速度)。
例如,如果我输入rm f<tab>
,它就会自动完成为rm foo\<space><space>
,如上面代码块中的最后一个例子一样。