使用 rm $(ls) 删除文件有什么缺点吗?

使用 rm $(ls) 删除文件有什么缺点吗?

我想知道使用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)'

相关内容