![长话短说](https://linux22.com/image/216833/%E9%95%BF%E8%AF%9D%E7%9F%AD%E8%AF%B4.png)
以下命令
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 目录)。