如何在find命令的-exec中使用两个bash命令?


32

在命令的-exec一部分中可以使用2 条find命令吗?

我已经尝试过类似的东西:

find . -name "*" -exec  chgrp -v new_group {}  ; chmod -v 770 {}  \;

我得到:

查找:-exec缺少参数
chmod:无法访问{}:没有这样的文件或目录
chmod:无法访问;:没有这样的文件或目录

Answers:


44

至于find命令,您也可以-exec连续添加更多命令:

find . -name "*" -exec chgrp -v new_group '{}' \; -exec chmod -v 770 '{}' \;

请注意,此命令的结果等同于使用

chgrp -v new_group文件&& chmod -v 770文件

在每个文件上。

所有find的参数,如-name-exec-size等等,其实都是测试find将继续由一个只要运行它们作为一个整个链条迄今已评估为。因此,仅当先前的-exec命令返回true(即命令的退出状态)时,执行每个连续的命令。但也了解逻辑运算符,例如()而不是()。因此,要使用一连串的测试而不考虑先前的结果,则需要使用以下内容:0find-o!-exec

find . -name "*" \( -exec chgrp -v new_group {} \; -o -exec chmod -v 770 {} \; \)

4
+1:是的,这是最优雅的方式。如果您能解释为什么使用'{}'(括号内的撇号),请访问:unix.stackexchange.com/q/8647/4485
用户

1
@user不幸的是,我不知道是否仍然有必要。我刚刚做了一些测试,还没有遇到可能会改变任何事情的情况。我猜这只是“好习惯”而已。
rozcietrzewiacz 2011年

2
引号对于名称中带有空格的文件很重要。
naught101 '16

17
find . -name "*" -exec sh -c 'chgrp -v new_group "$0" ; chmod -v 770 "$0"' {} \;

@Gilles:-c奇怪地处理$ 0 的奇迹使我每次看一眼都认为这是错误的,但它绝对正确。
derobert

我喜欢定义明确的外壳...
djangofan 2012年

对于给出的问题,此答案(和Giles的答案)似乎是更好的答案sh -c

14

首先,shell将您的命令解析为两个命令;,并用分隔,这等效于换行符:

find . -name "*" -exec chgrp -v new_group {}
chmod -v 770 {} \;

如果要运行shell命令,请使用显式调用shell bash -c(或者sh -c如果您不关心该shell是否专门为bash):

find . -name "*" -exec sh -c 'chgrp -v new_group "$0"; chmod -v 770 "$0"' {} \;

请注意使用{}作为shell的参数;它是第零个参数(通常是shell或脚本的名称,但这在这里无关紧要),因此称为"$0"

您可以一次将多个文件名传递给Shell,并使Shell遍历它们,这样会更快。在这里,我通过_了脚本名称,以下参数是文件名,这些文件名for x(的快捷方式for x in "$@")进行了迭代。

find . -name "*" -exec sh -c 'for x; do chgrp -v new_group "$x"; chmod -v 770 "$x"; done' _ {} +

请注意,由于bash 4或zsh中的内容,您根本不需要在这里查找。在bash中,运行shopt -s globstar(将其放入中~/.bashrc)以激活**/递归目录glob的身份。(在zsh中,此功能始终处于活动状态。)然后

chgrp -v new_group -- **/*; chmod -v 770 -- **/*

或者如果您想按顺序迭代文件

for x in **/*; do
  chgrp -v new_group -- "$x"
  chmod -v 770 -- "$x"
done

find命令的区别是外壳程序忽略点文件(名称以a开头的文件.)。首先将它们包括在bash中GLOBIGNORE=.:..;在zsh中,**/*(D)用作全局模式。


对于给出的问题,这个答案(和Glenn的答案)似乎是更好的答案sh -c
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.