如何递归地将目录的默认 ACL 应用于其后代?

fro*_*age 5 command-line bash acl permissions

如果我有一个分配了默认 ACL 条目的目录,但其部分或全部后代文件和子目录具有访问权限或默认 ACL 与这些默认值不一致,我如何递归(重新)应用这些默认 ACL 条目给所有后代?有资格。我希望完全替换所有现有的后代 ACL,除了文件的现有执行状态。否则的目的是所有后代都应该拥有在其当前位置新创建的 ACL。

Rogach 询问“如何在目录上递归设置权限(启用 ACL)?” 但希望以递归方式添加新的ACL 条目,而不是(重新)应用现有的默认 ACL。尽管 Rogach 没有要求,富兰克林·皮亚特 (Franklin Piat) 对该问题的回答也为我的问题提供了解决方案,但我认为他的解决方案存在缺陷。Piat 建议使用以下命令:

find . -mindepth 1 -type d| xargs -n 50 setfacl -b --set-file=<(getfacl . | sed -e 's/x$/X/')
find . -mindepth 1 -type f| xargs -n 50 setfacl -b --set-file=<(getfacl . | grep -v '^default:' | sed -e 's/x$/X/')
Run Code Online (Sandbox Code Playgroud)

我想修复的缺陷:

  • 当前目录的访问 ACL 被传播到后代而不是它的默认 ACL,这不是我理解的 ACL 应该如何工作。
  • 所有文件的执行位都被清除(sed无效)。
  • 当需要 root 权限时,典型的sudoer策略会阻止进程替换工作。请参阅sudoers(5) 的“closefrom_override”选项。

理想情况下,我也只需要一个命令行来完成这一任务。

fro*_*age 1

我想出了这个丑陋、低效的解决方案,但肯定有更好的方法:

\n\n
( cd \'/some/dir\' && sudo find . -mindepth 1 -path \'./leave/alone\' -prune -o \\( -type d -exec bash -c \'getfacl -cd . | sed -nre "p;/^\\$/!s/^/default:/p" | setfacl -bM - "{}"\' \\; \\) -o \\( -type f -exec bash -c \'getfacl -cd . | sed -re "/^#/!s/x\\$/X/" | setfacl -bM - "{}"\' \\; \\) )\n
Run Code Online (Sandbox Code Playgroud)\n\n

关于这个怪物的一些评论:

\n\n
    \n
  • 我已经包含了一个子目录排除来证明这种频繁的要求。
  • \n
  • cd消除了源目录路径中容易出错的重复,而外括号使该更改成为临时的
  • \n
  • 需要使用bash,因为“-exec”不允许管道。它还避免了 \'!\' 字符调用历史替换并导致臭名昭著的 \xe2\x80\x9cevent not found\xe2\x80\x9d 错误。
  • \n
  • 对于子目录,我们必须应用源默认ACL 作为访问 ACL默认 ACL。
  • \n
  • 对于文件,我们必须应用源默认 ACL 作为访问 ACL,但如果我们希望避免 \xe2\x80\x9cOnly 目录可以具有来自setfacl的默认 ACLs\xe2\x80\x9d 警告,则根本不应用默认 ACL 。
  • \n
  • 对于文件,我们需要将源默认 ACL 中的“x”权限替换为“X”,这样我们就不会最终强制所有文件变为可执行文件。该解决方案还保留了现有文件的可执行状态,但这只是因为我们使用 \xe2\x80\x9c-bM -\xe2\x80\x9d 而不是 \xe2\x80\x9c--set-file=-\xe2\x80 \x9d 与setfacl
  • \n
  • 这个命令行效率非常低,因为我不知道如何使用 \xe2\x80\x9c-exec ... +\xe2\x80\x9d 或xargs而不是 \xe2\x80\x9c-exec .. .\\;\xe2\x80\x9d。
  • \n
  • 此命令行有效,但请注意,后代文件获得的 ACL 与新创建新的后代文件时所发生的情况实际上等效,但在技术上并不等效
  • \n
\n\n

“Unix 哲学”非常棒,但是我想要完成的任务太频繁了,以至于不需要如此笨拙的命令行。除了游说setfacl中的附加功能之外,还有更好的方法吗?

\n