如果 find -exec 在其中一个文件上失败,如何退出

问题描述 投票:0回答:5

我想运行命令

find some/path -exec program \{} \; 

但我希望find命令一发出命令就退出

program \{}

找到的任何文件都失败。

有没有简单的方法可以做到这一点?

bash find exec exit
5个回答
14
投票

我认为仅靠

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

7
投票

除了其他好的答案之外,GNU find(至少)有一个

-quit
谓词:

find path -other -predicates \( -exec cmd {} \; -o -quit \)

-quit
谓词肯定是非标准的并且在BSD find中不存在。


2
投票

这是我的“构建系统”示例,它在遇到第一个编译器错误后停止 (基于小次郎的回答,这对我来说并不完全有效):

(确实需要转义括号。我知道这很伤人。)

find -name '*.cpp' \( -print -a -exec g++ -c {} \; -o -quit \)

我想构建一个基本上包含当前目录及以下目录中所有 C++ 文件的静态库。

在运行编译器之前,我想要文件

-print
-ed,然后
-exec
-ed,但是当它失败时(并在
stderr
上留下错误,它应该
-quit

-a
就像 shell 或 C 中的
&&
-o
就像
||

如果没有括号,GNU find 通过首先尝试最可能的条件来“优化”查询,这就是——我猜——

-quit


1
投票

您可以将输出从

find
传输到另一个子进程并使用
while
/
break
:

find some/path | while read f
do
    program $f
    if [ $? -ne 0 ]
    then
        break
    fi
done

0
投票
% _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}\" "{}" +
© www.soinside.com 2019 - 2024. All rights reserved.