如果该目录中其他用户不拥有任何内容,则返回该用户拥有的最顶层目录

如果该目录中其他用户不拥有任何内容,则返回该用户拥有的最顶层目录

采用以下目录结构和所有权:

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错误可能会导致误报。

相关内容