这个命令是如何工作的,以便在删除其子目录后删除父目录?

Tim*_*Tim 2 find

来自https://unix.stackexchange.com/a/24163/167166

find . -type d -depth -empty -exec rmdir "{}" \;
Run Code Online (Sandbox Code Playgroud)

这将首先向下钻取目录树,直到找到第一个空目录,然后将其删除。从而使父目录为空,然后将被删除,等等。这将产生预期的效果(我可能每周这样做 10 次,所以我很确定这是正确的)。:-)

它是如何工作的,以便在删除其子目录后删除父目录?

谢谢。

Ste*_*itt 9

find联机帮助页

-depth在目录本身之前处理每个目录的内容。该-delete动作也暗示-depth

find . -type d -depth -empty -exec rmdir "{}" \;
Run Code Online (Sandbox Code Playgroud)

find从当前目录开始,查找其中包含的所有文件和目录(以及子目录等);然后它处理每一个,在处理父目录之前从目录的内容开始。想象一下下面的树:

.
??? a
?   ??? c
?   ??? d
?       ??? e
??? b
Run Code Online (Sandbox Code Playgroud)

find . -depth 显示处理的顺序:

./a/c
./a/d/e
./a/d
./a
./b
.
Run Code Online (Sandbox Code Playgroud)

如您所见,子项列在父项之前。在更复杂的find命令中,操作将在父母之前应用于孩子;在您给出的示例中,将首先处理空的叶目录,如果它们为空,则删除;然后他们的父级将被处理,如果他们是空的(这可能是因为他们的空子级已被删除),也会被删除,依此类推,一直回到当前目录。

如果省略-depthfind则按枚举顺序处理文件,例如

.
./a
./a/c
./a/d
./a/d/e
./b
Run Code Online (Sandbox Code Playgroud)

所以.先处理;它不是空的,所以它被单独留下。然后a,同样适用。然后a/c; 因为它是空的,所以被删除了。a/d被留下,a/d/e被删除,原样b。但是find不会重新访问它已经处理过的目录,因此即使我们希望它们被删除aa/d仍然存在。

  • 作为附加说明:这里不能使用 `-exec rmdir {} +` 代替 `-exec rmdir {} \;` 以避免每个目录运行一个 `rmdir`,因为这会延迟运行,因此 `find` 会不要删除父对象,因为它在检查时不会为空(当累积足够的参数后运行 `rmdir` 时它会变为空)。对于包括你的一些 `find` 实现,你会导致使用 `-delete`(这意味着如前所述的 `-depth`,所以 `find . -type d -empty -delete` 就足够了)。这节省了 rmdir 执行并消除了一些竞争条件。 (5认同)