3

I have glossed over the man page for find and -quit seems to partly do what I want, except it will only cause find to return non-zero if an error has occurred. So how can find be forced to return non-zero or at least be spoofed into returning non-zero in a way that is readable to maintainers? So far I have this example:

$ find . -maxdepth 2 -type f \( -exec echo {} \; -o \( -printf "FAIL\n" -a -quit \) \)
./scooby
./shaggy
./velma
./daphne
./fred
$ echo $?
0

But if I replace the echo with a call to false, I get the desired early exit, but no non-zero exit code:

$ find . -maxdepth 2 -type f \( -exec false {} \; -o \( -printf "FAIL\n" -a -quit \) \)
FAIL
$ echo $?
0

Update:

I am trying to get find to return non-zero when -exec returns false, i.e. the command that executed returned non-zero. Currently, find just converts the non-zero -exec call into a boolean state to be used as part of a find expression.

$ find . -maxdepth 2 -type f \( -exec chmod a+x {} \; -o \( -printf "FAIL\n" -a -quit \) \)

This currently will never return non-zero if the chmod fails. I want to be able to return non-zero if the chmod fails, as well as exit early, which it already does using -quit.

Craig
  • 4,268
  • 4
  • 36
  • 53
  • What is it that you are trying to achieve (by returning a non-zero exit code)? – devnull Jan 21 '14 at 09:18
  • So is the objective to exit early when `chmod` fails or is there more to it? – devnull Jan 21 '14 at 09:43
  • 1
    Exit early (`-quit`) but also exit with a non-zero exit code. I was hoping `find` had some kind of `-exit 1` implementation, but can't see anything that stands out. – Craig Jan 21 '14 at 09:58

3 Answers3

4

If you always want to return a non-zero exit code, use && false as shown below:

find . -maxdepth 2 -type f ...  && false

Use grep to look for the the special FAIL string printed by find. It will return zero if the exec failed, non-zero otherwise.

$ find . -maxdepth 2 -type f \( -exec chmod a+x {} \; -o \( -printf "FAIL\n" -a -quit \) \) | grep -q "FAIL"
dogbane
  • 266,786
  • 75
  • 396
  • 414
2

find has the "plus" version of the -exec command. These actually exit with non-zero status, if one or more invocations of the command fail. So:

find . -maxdepth 2 -type f -exec false "{}" "+"

will give you the desired "fail" exit status. But it will execute your command (here false) only once, with all files found listed as arguments. So you need to use a command, that can handle a list of files, and that will exit a non-zero status, if processing any of the provided files failed.

Kai Petzke
  • 2,150
  • 21
  • 29
0

I think it is not a good idea to abuse the exit code of find to state a result. It will prevent find's standard way of reporting errors (e. g. I/O errors, permission denied errors, etc.).

I think you really should use some kind of output of find to state the result and check for that.

rm ./findResult 2>/dev/null
find /path/to/my/dir -name '*my*pattern*' -fprintf ./findResult "fail" -quit
result=$(cat ./findResult 2>/dev/null || echo "success")

This way you have a general way of returning values (not just 8 bit int but arbitrary strings). Using the exit code, on the other hand, will even cloak errors detected by find.

Alfe
  • 56,346
  • 20
  • 107
  • 159