I want to run the command
find some/path -exec program \\{} \\;
but I want the find command to quit as soon as the command
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.
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
print0
is used so that files with newlines in their names can be handled -0
is necessary when -print0
is used 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
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
% _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}\" "{}" +
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
.