我正在编写一个 bash 别名来修复在运行 Docker 时 Synology NAS 上不断出现混乱的权限。我只需要 chown & chmod /volume1/docker 目录中的所有内容(Synology 系统文件夹@eaDir
和#recycle
.
我已经尝试了这里可以使用的以下命令的每个版本,但到目前为止没有任何效果:
sudo find . \( ! -path '*/@eaDir/*' -o ! -path '*/\#recycle/*' \) -exec chown user:group {} +
起点是当前目录。我只需要排除@eaDir
and#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
和目录本身,并且如果不使用它们,它仍然会下降到其中并找到其中的所有文件。#recycle
exec
chown
更好的可能是:
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 D
is ( 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 {} +