如果子目录的执行权限被拒绝,“find -depth”的预期行为?

tox*_*lot 7 permissions directory find

我想知道我是否可以依赖使用findwith-depth选项时看到的行为,并且用户没有子目录的执行权限。

假设以下目录结构:

drwxrwxrwt. 10 root    root     12288 Mar 14 04:31 .
dr-xr-xr-x. 24 root    root      4096 Dec  6 03:33 ..
drwx------   4 root    root      4096 Mar 14 04:03 jen
Run Code Online (Sandbox Code Playgroud)

以非 root 用户身份运行以下命令:

find -type d
Run Code Online (Sandbox Code Playgroud)

输出是:

.
./jen
find: `./jen': Permission denied
Run Code Online (Sandbox Code Playgroud)

所以find找到目录jen并输出。然后它试图下降到jen,但没有许可,所以它打印了错误。上面的第一行打印到stdout,第二行打印到stderr

现在以非 root 用户身份运行以下命令:

find -depth -type d
Run Code Online (Sandbox Code Playgroud)

输出是:

find: `./jen': Permission denied
.
Run Code Online (Sandbox Code Playgroud)

因此,stdout除非用户具有列出目录内容的权限,否则不会输出路径名。

这个输出非常适合我想做的事情。但是,我不确定这是否只是巧合。我可以依赖这种行为吗?

我正在使用 GNU findutils 4.4.2。我想知道所有版本的find. 如果不是,它是否至少在所有版本的 GNU find 中都相同。

对我来说(对于这个用例)是否在第一个示例中打印jen并不重要。我只是想知道我是否可以依赖它在-depth使用时被排除在外。通常,依赖无证行为并不是一个好主意。但是,对我来说,这种副作用是有道理的。所以我认为这可能是预期的行为。

手册上说:

— 选项:-depth

在目录本身之前处理每个目录的内容。

正是我想要的,但不清楚目录本身的路径名是否会被排除在输出之外,如果它没有下降到其中。

感谢来自Hauke Laging一个提示,我发现我可以列出目录,并明确排除其中授予列出它们的内容被拒绝的目录:

find -type d \( \( -type d \( \! -executable -or \! -readable \) \) -prune -or -print \)
Run Code Online (Sandbox Code Playgroud)

这也具有停止“权限被拒绝”错误的效果,因为find如果没有权限,则永远不会尝试进入目录。

不幸的是,这不能满足我的需求有两个原因。

  • 我想要错误信息
  • 我需要这个-depth选项

从手册中引用

如果 '-depth' 选项有效,则无论如何都已经访问了子目录。因此,'-prune' 在这种情况下无效。

所以我回到了我开始的地方。

目前还不清楚是否“在目录本身之前处理每个目录的内容”。也意味着“如果您无法处理目录的内容,请不要处理它”。

Hau*_*ing 2

也许更好的方法是显式处理此类目录。我不知道这些是否是标准功能,但至少在 Gnu 中find这是可能的:

find . \( -type d \( \! -executable -or \! -readable \) \) -prune -or -type d
Run Code Online (Sandbox Code Playgroud)

当然,如果忽略目录,也可以打印一条消息:

find . \( -type d \( \! -executable -or \! -readable \) \) \
  -printf "Permission denied: %p\n" -prune -or -type d -print
Run Code Online (Sandbox Code Playgroud)