如何从 chown -R 中排除多个目录?

如何从 chown -R 中排除多个目录?

我正在编写一个 bash 别名来修复在运行 Docker 时 Synology NAS 上不断出现混乱的权限。我只需要 chown & chmod /volume1/docker 目录中的所有内容(Synology 系统文件夹@eaDir#recycle.

我已经尝试了这里可以使用的以下命令的每个版本,但到目前为止没有任何效果:

sudo find . \( ! -path '*/@eaDir/*' -o ! -path '*/\#recycle/*' \) -exec chown user:group {} +

起点是当前目录。我只需要排除@eaDirand#recycle以及其中的所有文件。有什么帮助吗?

答案1

您的逻辑错误,将匹配其路径不包含(例如, but is )或不包含(例如but is )\( ! -path '*/@eaDir/*' -o ! -path '*/\#recycle/*' \)的文件。唯一被排除的文件是其路径包含的文件/@eaDir/./foo/bar./#recycle/whatever/#recycle/./foo/bar./@eaDir/whatever两个都 /@eaDir//#recycle/(例如./#recycle/@eaDir/whatever).

相反,你会想要:

sudo find . ! '(' -path '*/@eaDir/*' -o -path '*/#recycle/*' ')' \
            -exec chown -h user:group {} +

或者:

sudo find . ! -path '*/@eaDir/*' \
            ! -path '*/#recycle/*' \
            -exec chown -h user:group {} +

或者:

sudo find . -path '*/@eaDir/*' -o \
            -path '*/#recycle/*' -o \
            -exec chown -h user:group {} +

另请注意-h,对于文件类型符号链接,更新的是符号链接,而不是其目标(可能位于某些系统内部,#recycle@eaDir可能位于系统中!)。

该方法仍然不安全,因为在find查找文件和chown启动以及更改其所有权之间存在竞争窗口,在此期间系统用户可以使用指向系统/敏感目录的符号链接替换目录组件。如果您的系统支持-execdir,则使用-exec它会有所帮助(但会花费更长的时间,因为chown需要运行多次,每个目录至少运行一次)。

另请注意,如果不是其中的文件,它仍然会 chown@eaDir和目录本身,并且如果不使用它们,它仍然会下降到其中并找到其中的所有文件。#recycleexecchown

更好的可能是:

find . '(' -name @eaDir -o -name '#recycle' ')' -prune -o \
       -exec chown -h user:group {} +

您还可以避免chown在已拥有的文件上运行user:group

find . '(' -name @eaDir -o -name '#recycle' ')' -prune -o \
       -user user -group group -o \
       -exec chown -h user:group {} +

与往常一样,-a当两个谓词之间省略时,a 就被隐含(-user user -group group是 的缩写-user user -a -group group),并且像在许多语言中一样,-a它的优先级高于-o: A -a B -o C -a Dis ( A -a B ) -o (C -a D)。因此,如果我们想非常明确,我们可以将上面的内容写成:

find .                                          \
  '('                                           \
    '(' -name @eaDir -o -name '#recycle' ')' -a \
    -prune                                      \
  ')' -o '('                                    \
    -user user -a -group group                  \
  ')' -o                                        \
  -exec chown -h user:group {} +

相关内容