我想运行命令
find some/path -exec program \{} \;
但我希望find命令一发出命令就退出
program \{}
找到的任何文件都失败。
有没有简单的方法可以做到这一点?
我认为仅靠
find -exec
是不可能实现你想要的。
最接近的替代方案是将
find
传输到 xargs
,如下所示:
find some/path -print0 | xargs -0 program
或
find some/path -print0 | xargs -0L1 program
如果程序以非零退出状态终止,这将退出
print0
以便可以处理名称中带有换行符的文件 -0
时需要
-print0
L1
告诉xargs
程序一次执行带有一个参数的程序(默认是在单次执行程序中添加所有参数)如果你只有正常的文件名,你可以像这样简化:
find some/path | xargs program
或
find some/path | xargs -L1 program
最后,如果程序需要多个参数,您可以将
-i
与 {}
结合使用。例如
find some/path | xargs -i program param1 param2 {} param4
除了其他好的答案之外,GNU find(至少)有一个
-quit
谓词:
find path -other -predicates \( -exec cmd {} \; -o -quit \)
-quit
谓词肯定是非标准的并且在BSD find中不存在。
这是我的“构建系统”示例,它在遇到第一个编译器错误后停止 (基于小次郎的回答,这对我来说并不完全有效):
(确实需要转义括号。我知道这很伤人。)
find -name '*.cpp' \( -print -a -exec g++ -c {} \; -o -quit \)
我想构建一个基本上包含当前目录及以下目录中所有 C++ 文件的静态库。
在运行编译器之前,我想要文件
-print
-ed,然后 -exec
-ed,但是当它失败时(并在 stderr
上留下错误,它应该 -quit
。
-a
就像 shell 或 C 中的 &&
而 -o
就像 ||
。
如果没有括号,GNU find 通过首先尝试最可能的条件来“优化”查询,这就是——我猜——
-quit
。
您可以将输出从
find
传输到另一个子进程并使用 while
/break
:
find some/path | while read f
do
program $f
if [ $? -ne 0 ]
then
break
fi
done
% _find_trap() {
> _find_pid="${1}" ; _find_ops="${2}" ; _find_trigger="${3}"
> shift 3 && set -- "${@}"
> trap 'kill -s INT "-${_find_pid}" \
> unset _find_pid _find_ops _find_trigger ; set - \
> 1>&2 printf "%s" "find killed due to trap" \
> exit [CODE] ' TRAP
> while { sh -c "${_find_ops} ${@}"} {
> [ "${_find_trigger}" ] && { kill -s TRAP "-${_find_pid}" ; break ; }
> ...
> }
> export -f _find_trap ; find . -execdir _find_trap \"$$\" \"${cmds}\" \
> \"${testable_trigger}\" "{}" +