我觉得我应该确切知道一些事情:如果我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).txt
和rm $(rand).txt
,论点“相同”,但结果却截然不同!
答案2
如果您正在考虑类似ls foo*.txt
vs. 的东西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 行为不谈,我们只关注rm
和ls
自己能处理什么。至少有一种情况ls
会显示rm
无法删除的内容涉及目录权限,另一种情况是特殊目录.
和..
。
文件夹权限
rm
是对目录的操作,因为通过删除文件,你将改变目录内容(或者换句话说,改变目录条目的列表,因为目录只不过是文件名和 inode 的列表)。这意味着您需要对目录具有写权限。即使您是该文件的所有者,如果没有目录权限,则无法删除文件。反之亦然:rm
如果您是目录所有者,可以删除可能由其他人拥有的文件。
因此,您很可能拥有某个目录的读取和执行权限,这将允许您遍历该目录并查看其中的内容,例如 ,但除非您是目录的所有者 或使用目录提升了您的权限,ls /bin/echo
否则您不能这样做。rm /bin/echo
/bin
sudo
你会在各处看到这样的案例。以下是其中一个案例: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
命令的内容。