ls 总是会列出 rm 将删除的文件吗?

ls 总是会列出 rm 将删除的文件吗?

我觉得我应该确切知道一些事情:如果我ls <something>,会rm <something>删除显示的完全相同的文件吗ls? 有什么情况可以删除未显示的rm文件吗?(这是在 18.04 bash 中)ls

编辑:感谢所有回答的人。我认为完整的答案是所有答案的组合,因此我接受了得票最多的答案作为“答案”。

在此过程中我学到了一些意想不到的东西:

  • ls在处理参数时并不像你想象的那么简单
  • 在简单、不费吹灰之力的 Ubuntu 安装中,.bashrc 别名ls
  • 不要以破折号开头命名文件,因为它们看起来像命令参数,并且命名一个 -r 就是要求这样做!

答案1

嗯,ls和都rm对传递给它们的参数进行操作。

这些参数可以是一个简单的文件,因此对同一个文件进行操作ls file.ext并且rm file.ext结果很明确(列出文件/删除文件)。

如果参数是目录,则ls directory列出内容目录不会按rm directory原样工作(即rm没有标志就无法删除目录,而如果你这样做rm -r directory,它会递归删除全部文件在下面directory 以及目录本身)。

但请记住,命令行参数可能会受到shell 扩展,所以不是始终保证如果参数包含通配符、变量、其他命令的输出等,则相同的参数将传递给两个命令。

举一个极端的例子,想想ls $(rand).txtrm $(rand).txt,论点“相同”,但结果却截然不同!

答案2

如果您正在考虑类似ls foo*.txtvs. 的东西rm foo*.txt,那么是的,它们将显示和删除相同的文件。 shell 扩展 glob,并将其传递给相关命令,然后命令对列出的文件进行操作。 一个列出它们,一个删除它们。

明显的区别是,如果这些文件恰好是目录,则将ls列出其内容,但rm无法将其删除。这通常不是问题,因为rm将删除较少的比所展示的要多ls

这里最大的问题来自于正在运行ls *rm *位于包含以破折号开头的文件名。它们会扩展为两个程序的命令行,就像您自己编写的一样,并且ls表示-r“反向排序”,而rm表示-r递归删除。如果您的子目录至少有两层深,则差异很重要。(ls *将显示第一级目录的内容,但rm -r *也会显示第一子级之后的所有内容。)

为了避免这种情况,请在允许的 glob 前面加上一个以./指示当前目录,和/或--在 glob 之前放置一个以表示选项处理的结束(即rm ./*rm -- *)。

对于像 这样的 glob *.txt,这实际上不是一个问题,因为点是一个无效的选项字符,并且会导致错误(直到有人扩展实用程序来为其发明一个含义),但./无论如何把 放在那里仍然更安全。


当然,如果您更改了 shell 的通配符选项,或者在命令之间创建/移动/删除了文件,那么这两个命令也可能得到不同的结果,但我怀疑您指的是上述任何一种情况。(处理新的/移动的文件会非常麻烦,无法安全地完成。)

答案3

撇开 shell 行为不谈,我们只关注rmls自己能处理什么。至少有一种情况ls会显示rm无法删除的内容涉及目录权限,另一种情况是特殊目录...

文件夹权限

rm是对目录的操作,因为通过删除文件,你将改变目录内容(或者换句话说,改变目录条目的列表,因为目录只不过是文件名和 inode 的列表)。这意味着您需要对目录具有写权限。即使您是该文件的所有者,如果没有目录权限,则无法删除文件。反之亦然rm如果您是目录所有者,可以删除可能由其他人拥有的文件。

因此,您很可能拥有某个目录的读取和执行权限,这将允许您遍历该目录并查看其中的内容,例如 ,但除非您是目录的所有者 或使用目录提升了您的权限,ls /bin/echo否则您不能这样做。rm /bin/echo/binsudo

你会在各处看到这样的案例。以下是其中一个案例:https://superuser.com/a/331124/418028


特殊目录 '.' 和 '..'

另一个特殊情况是...目录。如果你执行ls .ls ..,它会很乐意向你显示内容,但rm不允许 'ing 它们:

$ rm -rf .
rm: refusing to remove '.' or '..' directory: skipping '.'

答案4

ls *并且rm *不负责扩展 glob - 这是由 shell 在将其传递给命令之前完成的。

这意味着您可以使用任何带有扩展文件列表的命令-所以我会使用尽可能少的操作。

因此,实现此目的的更好方法(或至少另一种方法)是跳过中间人。

echo *将向您准确显示传递给您的rm命令的内容。

相关内容