长话短说

长话短说

以下命令

mkdir -p /tmp/test/foo /tmp/test/bar && \
find /tmp/test/ -mindepth 1 -type d \
-exec echo Deleting "{}" \; \
-exec rm -rv "{}" \;

我希望打印

Deleting /tmp/test/foo
removed directory '/tmp/test/foo'
Deleting /tmp/test/bar
removed directory '/tmp/test/bar'

(根据第一个-exec语句)并删除相应的目录(根据第二个-exec语句)。好吧,从技术上讲,这确实是正在发生的事情并打印在 stdout 上 - 但 stderr 上还有 2 行。

Deleting /tmp/test/foo
removed directory '/tmp/test/foo'
find: ‘/tmp/test/foo’: No such file or directory
Deleting /tmp/test/bar
removed directory '/tmp/test/bar'
find: ‘/tmp/test/bar’: No such file or directory

所以/似乎/第二个-exec语句调用rm -rv发出了两次。

  • 为什么/这里到底发生了什么?
  • 我怎样才能实现我真正期望从上述命令中得到的结果?

答案1

长话短说

您对警告消息感到困惑,find这些警告消息看起来与错误消息相似,rm您认为 rm 正在每个目录中被调用多次,但事实并非如此。在命令-depth中添加 afind将停止警告并给出预期的输出。

解释

如果你的目录结构稍微复杂一点,那就更清楚了。您目前有

$ tree /tmp/test
/tmp/test
├── bar
└── foo

但如果你说

/tmp/test
├── bar
└── foo
    └── wibble
        └── hello.txt

那么您可以看到您的示例 find 命令并没有多大意义。在目录中找到文件的顺序是没有定义的,但让我们假设它foo先找到 ,然后找到bar。该命令将首先删除 foo 子树,因此将删除 /tmp/test/foo/wibble/hello.txt、/tmp/test/foo/wibble,然后删除 /tmp/test/foo。然后它将尝试处理foo刚刚删除的目录,提示它生成警告消息。然后它将继续执行 /tmp/test 中的下一件事,即bar.它会删除它,然后尝试进入bar刚刚删除的目录,并再次打印一条警告消息。

如果将 a 添加-depth到 find 命令,则会处理目录他们的子目录。所以顺序是 /tmp/test/foo/wibble (这将删除 /tmp/test/foo/wibble/hello.txt 和 /tmp/test/foo/wibble),然后是 /tmp/test/foo (这将删除删除现在空的 /tmp/test/foo 目录),然后删除 /tmp/test/bar (这将删除 /tmp/test/bar 目录)。

相关内容