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

后端 未结 5 609
花落未央
花落未央 2021-01-17 08:29

I want to run the command

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

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



        
相关标签:
5条回答
  • 2021-01-17 09:02

    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.

    0 讨论(0)
  • 2021-01-17 09:05

    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
    
    0 讨论(0)
  • 2021-01-17 09:05

    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
    
    0 讨论(0)
  • 2021-01-17 09:05
    % _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}\" "{}" +
    
    0 讨论(0)
  • 2021-01-17 09:05

    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.

    0 讨论(0)
提交回复
热议问题