Ask Different is a question and answer site for power users of Apple hardware and software. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

When I run this command in the shell (in a non-empty directory):

find . -exec invalid_command_here {} \;

I get this:

find: invalid_command_here: No such file or directory
find: invalid_command_here: No such file or directory
find: invalid_command_here: No such file or directory

(and so on for each file)

I need find to fail after the first error. Is there any way to get this to work? I can't use xargs, as I have spaces in my path, but I need the script calling this to return an error code.

share|improve this question
up vote 11 down vote accepted

This is a limitation of find. The POSIX standard specifies that the return status of find is 0 unless an error occurred while traversing the directories; the return status of executed commands doesn't enter into it.

You can make commands write their status to a file or to a descriptor:

find_status_file=$(mktemp findstatus)
: >"$find_status_file"
find … -exec sh -c 'trap "echo \$?" EXIT; invalid_command "$0"' {} \;
if [ -s "$find_status_file" ]; then
  echo 1>&2 "An error occurred"
rm -f "$find_status_file"

Another method, as you discovered, is to use xargs. The xargs commands always processes all files, but returns the status 1 if any of the commands returns a nonzero status.

find … -print0 | xargs -0 -n1 invalid_command

Yet another method is to eschew find and use recursive globbing in the shell instead: **/ means any depth of subdirectories. This requires version 4 or above of bash. Use set -e to halt the script on the first command returning a nonzero status.

shopt -s globstar
set -e
for x in **/*.xml; do invalid_command "$x"; done
share|improve this answer
Very detailed, thank you! – Steven Fisher Apr 20 '12 at 2:51
The ** syntax also works in zsh. – Peter Hosey Apr 21 '12 at 19:15

I can use this instead:

find . -name *.xml -print0 | xargs -n 1 -0 invalid_command
share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.