使用“ find ... -exec sh -c'...'sh {} +”的find命令如何工作?

你好

@StephaneChazelas针对此问答发布了以下解决方案:使用“ find -exec {} +”遇到一些麻烦

$ find . -iname "*.extension" -exec sh -c '
  exec <command> "$@" <additional parameters>' sh {} +

这到底是怎么回事?具体来说,最后一个是sh {}做什么的?似乎只是为了平息find的-exec命令而已,以便它可以做一些事情,即NOOP。

我可以很容易地放在echo {}那儿,它似乎工作得很好。

斯蒂芬·查泽拉斯(Stephane Chazelas)

语法为:

find ... -exec cmd {} +

find会根据中的条件找到许多文件,...cmd以该文件路径列表作为参数运行,并在不超过命令参数大小限制的情况下,尽可能多地运行该文件路径。

如果需要,它可以拆分文件列表并cmd多次调用例如,它可能最终调用:

cmd ./file1 ./file2 ... ./file3000
cmd ./file3001 ./file3002 ... ./file4321

这样做的局限性是{}必须持续到最后。例如,您不能写:

find ... -exec cmd {} other args +

就像您可以';'代替'+'

你可以写:

find ... -exec echo foo {} +

但不是:

find ... -exec echo {} foo +

因此,如果确实需要在cmd文件列表之后添加一些额外的参数,则必须诉诸shell。(需要调用shell的其他原因是在需要使用shell功能(例如重定向,管道,某些字符串扩展...)的任何时候。)

在中sh -c 'inline-script' x a b c,因为inline-script$0is x$1is a$2is b...,所以"$@"这3个参数的列表也是如此:a,b和c。所以在:

find ... -exec sh -c 'cmd "$@" other arg' find-sh {} +

对于内联脚本$0(例如,在显示错误消息时使用)设置为,find-sh并且"$@"是文件列表(find扩展{}的列表)。

通过使用execshell特殊内置函数:

find ... -exec sh -c 'exec cmd "$@" other arg' find-sh {} +

我们告诉外壳程序不要派生一个额外的进程来运行cmd,而要在同一进程中运行(用该命令替换正在运行的外壳程序进程)。某些外壳程序(如bashzsh和的某些实现对ksh脚本中的最后一个命令隐式地执行此操作。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章