How to exit from find -exec if it fails on one of the files

丶灬走出姿态 提交于 2019-12-04 02:54:31

问题


I want to run the command

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

but I want the find command to quit as soon as the command

 program \{}

fails on any of the files found.

Is there a simple way of doing this?


回答1:


I think it is not possible to achieve what you want, only with find -exec.

The closest alternative would be to do pipe find to xargs, like this:

find some/path -print0 | xargs -0 program

or

find some/path -print0 | xargs -0L1 program

This will quit if program terminates with a non-zero exit status

  • the print0 is used so that files with newlines in their names can be handled
  • -0 is necessary when -print0 is used
  • the L1 tells xargs program to execute program with one argument at a time (default is to add all arguments in a single execution of program)

If you only have sane file names, you can simplify like this:

find some/path | xargs program

or

find some/path | xargs -L1 program

Finally, If program takes more than one argument, you can use -i combined with {}. E.g.

find some/path | xargs -i program param1 param2 {} param4



回答2:


In addition to the other fine answers, GNU find (at least) has a -quit predicate:

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

The -quit predicate is certainly non-standard and does not exist in BSD find.




回答3:


You could pipe the output from find to another subprocess and use while/break:

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



回答4:


% _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}\" "{}" +



回答5:


Here is my example for a "build system", which stops after hitting the first compiler error (based on Kojiro's answer, which did not exaclty work for me):

(The need for escaped parentheses is real. I know that hurts.)

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

I want to build a static library of basically all C++ files located in the current directory and below.

Before running the compiler I want to have the file -print-ed, then -exec-ed, but when it fails (and leaves errors on stderr, it should -quit.

-a is like && and -o is like || in shell or C.

Without the parentheses, GNU find "optimizes" the query, by trying the most probable condition first, which is -- I guess -- -quit.



来源:https://stackoverflow.com/questions/14871147/how-to-exit-from-find-exec-if-it-fails-on-one-of-the-files

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!