我想知道使用rm $(ls)
它来删除文件(或rm -r $(ls)
删除目录)是否安全?因为在所有网站上,人们都提供了其他方法来执行此操作,尽管此命令似乎比其他命令容易得多。
答案1
不,它并不安全,而且常用的替代品rm *
也并不安全。
有许多的问题rm $(ls)
。正如其他人在他们的答案中已经提到的那样,的输出ls
将在内部字段分隔符。
最好的情况是,它根本不起作用。最坏的情况是,您只想删除文件(而不是目录)——或者有选择地删除一些文件-i
——但当前目录中有一个同名的文件c -rf
。让我们看看会发生什么。
$ mkdir a
$ touch b
$ touch 'c -rf'
$ rm -i $(ls)
$ ls
c -rf
该命令rm -i $(ls)
本来应该只删除文件,并在删除每个文件之前询问,但最终执行的命令是 read
rm -i a b c -rf
所以它做了一些完全不同的事情。
请注意,这rm *
只是略有改善。如果目录结构与之前相同,它将按预期运行,但如果您有一个名为的文件-rf
,您仍然运气不佳。
$ mkdir a
$ touch b
$ touch ./-rf
$ rm -i *
$ ls
-rf
有几种更好的选择。最简单的方法只涉及R M和通配符。
命令
rm -- *
将完全按照预期工作,其中
--
信号表示其后的所有内容不应被解释为选项。二十多年来,这一直是 POSIX 实用程序语法指南的一部分。它应用广泛,但您不应期望它无处不在。
命令
rm ./*
使得 glob 以不同的方式扩展,因此不需要被调用实用程序的支持。
对于我上面的例子,你可以看到最终将通过添加回声。
$ echo rm ./* rm ./a ./b ./-rf
领先的
./
防止R M避免意外地将任何文件名视为选项。
答案2
这是为了做什么?
ls
列出当前目录中的文件$(ls)
替代ls
作为参数的地方的输出rm
- 本质上
rm $(ls)
是为了删除当前目录中的所有文件
这张照片有什么问题?
ls
无法正确处理文件名中的特殊字符。Unix 用户通常建议使用不同的方法。我也证明了有关计算文件名的相关问题。 例如:
$ touch file$'\n'name
$ ls
file?name
$ rm $(ls)
rm: cannot remove 'file': No such file or directory
rm: cannot remove 'name': No such file or directory
$
此外,正如 Denis 的回答中正确提到的那样,带有前导破折号的文件名可能会被解释为rm
替换后的参数,这违背了删除文件名的目的。
什么有效
您想删除当前目录中的文件。因此使用 glob rm *
:
$ ls
file?name
$ rm $(ls)
rm: cannot remove 'file': No such file or directory
rm: cannot remove 'name': No such file or directory
$ rm *
$ ls
$
您可以使用find
命令。此工具通常推荐用于当前目录以外的用途 - 它可以递归遍历整个目录树,并通过以下方式对文件进行操作-exec . . .{} \;
$ touch "file name"
$ find . -maxdepth 1 -mindepth 1
./file name
$ find . -maxdepth 1 -mindepth 1 -exec rm {} \;
$ ls
$
Python 不会处理文件名中的特殊字符,因此我们也可以使用它(请注意,这仅适用于文件,如果您想操作目录,则需要使用os.rmdir()
和):os.path.isdir()
python -c 'import os; [ os.remove(i) for i in os.listdir(".") if os.path.isfile(i) ]'
事实上,为了简洁起见,上面的命令可以转换为函数或别名~/.bashrc
。例如,
rm_stuff()
{
# Clears all files in the current working directory
python -c 'import os; [ os.remove(i) for i in os.listdir(".") if os.path.isfile(i) ]'
}
Perl 版本如下
perl -e 'use Cwd;my $d=cwd();opendir(DIR,$d); while ( my $f = readdir(DIR)){ unlink $f;}; closedir(DIR)'