出于测试目的,我创建了以下目录。
user@linux:~$ mkdir dir0{1..3}
user@linux:~$ ls -l
total 12K
drwxr-xr-x 2 user user 4.0K Mei 31 10:45 dir01
drwxr-xr-x 2 user user 4.0K Mei 31 10:45 dir02
drwxr-xr-x 2 user user 4.0K Mei 31 10:45 dir03
user@linux:~$
然后,我删除了它find -exec
user@linux:~$ find -type d -exec rmdir {} \;
rmdir: failed to remove '.': Invalid argument
find: ‘./dir02’: No such file or directory
find: ‘./dir01’: No such file or directory
find: ‘./dir03’: No such file or directory
user@linux:~$
目录已删除,我已验证。
user@linux:~$ ls -l
total 0
user@linux:~$
我的问题是:
1)我不明白为什么会有这些消息。知道为什么吗?
rmdir: failed to remove '.': Invalid argument
find: ‘./dir02’: No such file or directory
我没有看到这种错误rmdir
user@linux:~$ mkdir dir0{1..3}
user@linux:~$
user@linux:~$ ls -l
total 12K
drwxr-xr-x 2 user user 4.0K Mei 31 22:58 dir01
drwxr-xr-x 2 user user 4.0K Mei 31 22:58 dir02
drwxr-xr-x 2 user user 4.0K Mei 31 22:58 dir03
user@linux:~$
user@linux:~$ rmdir *
user@linux:~$
user@linux:~$ ls -l
total 0
user@linux:~$
2)是否可以删除这些消息?
答案1
您会收到“没有这样的文件或目录”错误,find
因为find
正在尝试输入刚刚删除的目录。默认情况下,它会将其操作应用于当前访问的目录中的所有匹配内容,然后再继续进入子目录。
添加到make-depth
的调用中,对其搜索路径进行深度优先搜索,这反过来意味着,如果您在目录上执行,它将已经访问过该目录,并且不会尝试再次访问该目录。find
find
rmdir
由于这个原因(在has的实现中),该-depth
选项是隐含的。-delete
find
-delete
find . -depth -type d -exec rmdir {} \;
-depth
是该实用程序的标准选项find
。
请注意,rmdir
仅适用于空目录。如果您有很多非空目录,上面的命令会产生很多错误消息。
相反,如果您find
支持它,请使用-empty
:
find . -type d -empty -delete
这将删除空目录。
与 afind
没有非标准-delete
也-emtpy
:
find . -depth -type d -exec sh -c '
for dirpath do
set -- "$dirpath"/*
[ ! -e "$1" ] && rmdir "$dirpath"
done' sh {} +
这将测试找到的目录是否为空,如果是,则将其删除。
这是一段很长的代码,以避免由于目录非空而看到一些错误消息,但任何错误消息是希望生成的内容会更有趣,因为它们可能是“权限被拒绝”错误。将错误重定向到顶部的/dev/null
第一个命令中会隐藏此类错误。find
答案2
大概发生的情况是,通过-exec ... \;
构造, find 逐步完成其工作:
- 遍历目录树,查找匹配的条目
-type d
,以及 rmdir
一旦发现此类条目,就立即运行。
这意味着,在您的示例中, find 将查看dir01
,将其作为稍后输入的目录记住,然后rmdir
在其上运行,然后,当尝试递归到 时dir01
,会失败,因为它不再存在。
在这种情况下运行 with应该会有所帮助:将发出-exec rmdir {} +
单个调用。rmdir dir01 dir02 dir03
这消除了最后三个错误消息。
错误信息.
是因为,嗯.
,当前目录确实是一个目录,但不是一个rmdir
可以删除的目录,因为它不为空。使用-min-depth
停止考虑它,发出命令:
find -mindepth 1 -type d -exec rmdir {} +
这并不完美;嵌套目录或大量匹配目录仍然可能导致打印错误消息,但这应该适用于问题的简单情况。