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

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

是否可以在命令-exec部分使用2个命令find

我尝试过类似的事情:

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

我得到:

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

答案1

至于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命令都会被执行除非之前的返回真的(即0命令的退出状态)。但find也理解逻辑运算符,例如或者-o) 和不是( !)。因此,使用一系列-exec测试不管对于之前的结果,需要使用如下内容:

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

答案2

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

答案3

您的命令首先被 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 的参数;它是第 0 个参数(通常是 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是 shell 忽略点文件(名称以 开头的文件.)。要包含它们,在 bash 中,首先设置GLOBIGNORE=.:..;在 zsh 中,用作**/*(D)glob 模式。

相关内容