我想chmod go+w
在包括隐藏文件的特定文件夹中递归运行,我首先尝试
find . -name ".*" -o -name "*" -exec chmod go+w {} \;
但我发现它不会影响隐藏文件。为了检查自己,我跑了
find . -name ".*" -o -name "*"
并列出了隐藏文件。我还注意到,如果我排除该-o -name "*"
部分,它将 chmod 隐藏文件(但当然排除非隐藏文件)。我最后一次尝试是使用 xargs 代替
find . -name ".*" -o -name "*" | xargs chmod go+w
最终按预期工作。我在第一个片段中做错了什么?
红帽企业 Linux 服务器版本 6.8(圣地亚哥)
GNU bash,版本 4.3.42(1)-release (x86_64-unknown-linux-gnu)
答案1
解决方案是将两个名称测试用括号绑定在一起。
为了说明这一点,让我们考虑一个包含三个常规文件的目录:
$ ls -a
. .. .hidden1 .hidden2 not_hidden
现在,让我们看看原来的命令:
$ find . -name ".*" -o -name "*" -exec echo Found {} \;
Found ./not_hidden
仅找到非隐藏文件。
接下来,让我们添加括号将两个名称测试分组在一起:
$ find . \( -name ".*" -o -name "*" \) -exec echo Found {} \;
Found .
Found ./not_hidden
Found ./.hidden1
Found ./.hidden2
所有文件都找到了。
解决方案是使用括号。
更多细节
-name "*"
在原始命令中,和 之间没有运算符-exec ... \;
。因此,find
假定默认运算符是逻辑与。因为逻辑与比逻辑或 ( -o
) 绑定更紧密,这意味着该命令被解释为:
find . \( -name ".*" \) -o \( -name "*" -exec echo Found {} \; \)
这意味着exec
仅当第一个name
条件不匹配时才运行。
欲了解更多信息,请参阅运营商中的部分man find
。
没有的话会发生什么-exec
让我们尝试使用一个简单的-print
:
$ find . -name ".*" -o -name "*" -print
./not_hidden
正如您所看到的,与上面的隐式逻辑“and”-print
绑定在一起。-name "*"
但是,考虑一下在没有指定任何操作的情况下会发生什么:
$ find . -name ".*" -o -name "*"
.
./not_hidden
./.hidden1
./.hidden2
到这里,所有的文件都找到了。原因是,在这个版本中-o
,仅有的操作员。