采用以下目录结构和所有权:
userA ./dir1
userA ./dir1/dir1.1
userA ./dir1/dir1.2
userA ./dir2
userA ./dir2/dir2.1
userA ./dir2/dir2.1/dir2.1.1
userB ./dir2/dir2.2
userB ./dir3
运行find . -type d -user userA
将返回:
./dir1
./dir1/dir1.1
./dir1/dir1.2
./dir2
./dir2/dir2.1
./dir2/dir2.1/dir2.1.1
但我希望看到这个输出:
./dir1
./dir2/dir2.1
dir1.1
并且dir1.2
不会被返回,因为没有其他用户拥有dir1
.- 同样,
dir2.1.1
也不返回。 dir2
不会返回(尽管它属于 userA),因为dir2.2
它属于 userB。
这对于磁盘清理很有用,因此用户可以识别哪些目录可以“安全”运行rm -rf
。当有数十亿个文件时du
具有非常高的运行时间。此外,限制搜索深度也无济于事,因为目录可能位于任何层次结构级别。
答案1
使用这个脚本:
#!/bin/sh -
u="$1"
shift
find "$@" -type d -user "$u" ! -exec sh -c '
find "$2" -type d ! -user "$1" | grep -qm 1 .
' find-sh "$u" {} \; -prune -print
用法示例:
/path/to/the_script userA ./
第一个参数(此处userA
)是用户名。接下来的所有内容(此处./
)都将传递给find
;您应该以这种方式传递起始路径(尽管注入测试在技术上是可能的)。
该脚本使用 mainfind
查找用户拥有的目录。对于此类目录,find
会调用另一个目录,它会查找不属于用户的子目录。如果没有,则删除该目录(因此 mainfind
不会检查其子目录)并打印其路径名。
笔记:
- 如果内部
find
发现任何内容,则外部(主)find
将不会修剪该目录,而是会检查其子目录。如果内部find
发现的内容很深,那么在脚本移动到目录树的另一个分支之前,将“徒劳地”检查不同级别的许多子目录多次。除非目录树非常大,否则操作系统应该缓存元数据,并且下一次find
检查同一子目录应该很快。多次检查似乎不是最理想的,但任何优化此操作的尝试都会使代码变得复杂;海事组织这是不值得的。 grep -m 1
在第一次匹配后退出,但此选项不可移植。如果您grep
不支持,-m
那么就不要使用它(即使用grep -q .
)。该脚本会比较慢,但它会起作用。find-sh
解释如下:中的第二个 sh 是什么sh -c 'some shell code' sh
?- 标题说“如果其他用户不拥有任何内容”,但您的示例和用例表明“如果另一个用户没有子目录拥有”。我的脚本仅检查(子)目录。要检查“如果没有……”,请忽略
-type d
内部调用中的测试find
。 Permission denied
错误可能会导致误报。