pos*_*ing 13 command-line delete files rm directory
我想知道使用rm $(ls)
删除文件(或rm -r $(ls)
删除目录)是否安全?因为在所有网站中,即使此命令看起来比其他命令容易得多,人们也会提供其他方法来执行此操作。
Den*_*nis 26
不,它不安全,常用的替代rm *
方法也不是很安全。
有很多问题rm $(ls)
。正如其他人在他们的答案中已经涵盖的那样, 的输出ls
将在内部字段分隔符中存在的字符处进行拆分。
最好的情况,它根本不起作用。最坏的情况是,您打算只删除文件(而不是目录)——或者有选择地删除一些文件-i
——但是c -rf
在当前目录中有一个同名的文件。让我们看看发生了什么。
$ mkdir a
$ touch b
$ touch 'c -rf'
$ rm -i $(ls)
$ ls
c -rf
Run Code Online (Sandbox Code Playgroud)
该命令rm -i $(ls)
应该只删除文件并在删除每个文件之前询问,但最终执行的命令读取
rm -i a b c -rf
Run Code Online (Sandbox Code Playgroud)
所以它完全做了别的事情。
请注意,这rm *
只是稍微好一点。与以前的目录结构一样,它将在这里按预期运行,但是如果您有一个名为 的文件-rf
,您仍然不走运。
$ mkdir a
$ touch b
$ touch ./-rf
$ rm -i *
$ ls
-rf
Run Code Online (Sandbox Code Playgroud)
有几个更好的选择。最简单的只涉及rm和 globbing。
命令
rm -- *
Run Code Online (Sandbox Code Playgroud)
将完全按预期工作,其中--
表示不应将其后的所有内容解释为选项。
二十多年来,这一直是 POSIX 实用程序语法指南的一部分。它很普遍,但你不应该期望它无处不在。
命令
rm ./*
Run Code Online (Sandbox Code Playgroud)
使 glob 以不同方式扩展,因此不需要被调用实用程序的支持。
对于我上面的示例,您可以看到最终将通过添加echo来执行的命令。
$ echo rm ./*
rm ./a ./b ./-rf
Run Code Online (Sandbox Code Playgroud)
前导./
可防止rm意外地将任何文件名视为选项。
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
$
Run Code Online (Sandbox Code Playgroud)
此外,正如 Denis 的回答中正确提到的,带有前导破折号的文件名可以解释为rm
after 替换的参数,这违背了删除文件名的目的。
您要删除当前目录中的文件。所以使用 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
$
Run Code Online (Sandbox Code Playgroud)
您可以使用find
命令。这个工具经常被推荐用于不仅仅是当前目录 - 它可以递归遍历整个目录树,并通过-exec . . .{} \;
$ touch "file name"
$ find . -maxdepth 1 -mindepth 1
./file name
$ find . -maxdepth 1 -mindepth 1 -exec rm {} \;
$ ls
$
Run Code Online (Sandbox Code Playgroud)
Python没有问题,文件名中使用特殊字符,这样我们就可以采用这种方法(注意,这只是一个是文件,则需要使用os.rmdir()
和os.path.isdir()
,如果你想上的目录操作):
python -c 'import os; [ os.remove(i) for i in os.listdir(".") if os.path.isfile(i) ]'
Run Code Online (Sandbox Code Playgroud)
事实上,~/.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) ]'
}
Run Code Online (Sandbox Code Playgroud)
Perl 版本将是
perl -e 'use Cwd;my $d=cwd();opendir(DIR,$d); while ( my $f = readdir(DIR)){ unlink $f;}; closedir(DIR)'
Run Code Online (Sandbox Code Playgroud)