如何可靠地 rm -fr *?

How to rm -fr * reliably?

rm -fr *

不会删除.files

另一方面,

rm -fr * .*

会删太多!

有没有可靠的方法递归删除Bash中目录的所有内容?

我能想到的一种方法是:

rm -fr $PWD
mkdir $PWD
cd $PWD

这有暂时删除 $PWD 的副作用。

我建议先用:

shopt -s dotglob

dotglob: If set, bash includes filenames beginning with a . in the results of pathname expansion

rm -fr * .*

相对"safe"。 rm 被 POSIX 禁止作用于 ...

rm -rf . .. 

将是一个空操作,尽管它会 return 1. 如果你不想要错误 return,你可以这样做:

rm -rf .[!.]* 

这是 POSIX 标准化的,不需要 bash 扩展。

您还可以使用查找:

find . -delete 

您可以将 find-delete-maxdepth 一起使用:

find . -name "*" -delete -maxdepth 2

假设您在目录 temp 中,如下所示:

./temp
     |_____dir1
     |        |_____subdir1
    X|_file  X|_file      |_file
     |
    X|_____dir2
             X|_file

查看树,旁边有 X 的文件和目录将使用上面的命令删除。 subdir1 幸免于难,因为 find 将删除文件的最大深度设置为 2,并且其中有一个文件。 find 将删除以 . 开头的文件 — 但是,它不适用于符号链接。

 -delete
         Delete found files and/or directories.  Always returns true.
         This executes from the current working directory as find recurses
         down the tree. It will not attempt to delete a filename with a
         ``/'' character in its pathname relative to ``.'' for security
         reasons. Depth-first traversal processing is implied by this
         option. Following symlinks is incompatible with this option.

对于 UNIX,通常的智慧是使用像这样的东西:

rm -rf * .[!.]* ..?*

这将列出所有以点或双点开头的文件(不包括普通双点 (./..)。

但是,如果该类型的文件不存在,则通配扩展将保留星号。

让我们测试一下:

$ mkdir temp5; cd temp5
$ touch {,.,..}{aa,bb,cc}
$ echo $(find .)
. ./aa ./cc ./..bb ./..aa ./.cc ./.bb ./..cc ./.aa ./bb

而且,如前所述,这将包括所有文件:

$ echo * .[!.]* ..?*
aa bb cc .aa .bb .cc ..aa ..bb ..cc

但如果其中一种类型不存在,星号将保留:

$ rm ..?*
$ echo * .[!.]* ..?*
aa bb cc .aa .bb .cc ..?*

我们需要避免使用包含星号的参数来解决此问题。