Ignore errors with unix' find alternative ?

Hi everyone,

I have this script which searches for a file, but I want it to ignore errors and continue. Under “Ignore Errors” in http://en.wikipedia.org/wiki/Find they give a few options, I can only get this to work

find / -name "myfile" -type f -print 2>/dev/null

But when it doesn’t find any files it returns the non-zero status. I want it to return “” (<- nothing, just like regular “find”)
There’s also

find . -name "myfile" |& grep -v "Permission denied"

Which I can’t get to work with the quotes… Isn’t a quote the same as " in AppleScript?

Anyway, here’s what I have without the error ignoring.

do shell script "find -E " & quoted form of SearchFolder & " -path " & quoted form of ExcludeFolder & " -prune -o -type f -iregex '.*(" & SearchName & "|" & SearchName2 & ").*' -maxdepth " & MaxDepth

Thanks

Try adding “;true” to the end of your command. That will prevent the overall command sequence from returning a “failure” (non-zero) exit code. There is usually no need to redirect the stderr since it will be discarded when do shell script finds that the final exit code is not a “failure” code.

The big problem with adding “;true” is that genuine errors are also hidden. A plain do shell script “find . -blah” will throw an error to let you know that “-blah” is not a valid option. But do shell script “find . -blah;true” will only return an empty string. Unfortunately both syntax errors and “encountered a permission problem” are both signaled by returning exit code 1, so they are hard to rigorously distinguish in an automated fashion. You could capture the stdout and stderr messages and then if find exits with a non-zero code, check that the captured stderr output only contains innocuous problems (like the permission messages) and then exit successfully (if there are unrecognized or problematic errors in the stderr log then dump the saved stderr output to the real stderr and exit with the original exit code from find). Not nearly impossible, but neither is it a “one liner” or small addition to your existing do shell script code.

As you noticed, your first method (2>/dev/null) suppresses the error messages, but it leaves the exit code unchanged, so back in AppleScript-land do shell script still throws an error.

Your second method is workable. I am not sure what problems you had with it. It does have yet another failure mode though. If all the output (both stdout and stderr) matches the pattern you are using with “-v”, grep will return a failure exit code since it was not able to print anything. Also if there were any files or directories that had names that match your pattern (unlikely, but not impossible), they would be filtered out. This technique also suffers from the same “hides genuine errors” that adding “;true” does (since the main exit code now comes from grep and it will return success as long as it was able to print something out).

Thanks chrys.

Adding ;true gives me “” when there are no files :slight_smile:

I was testing the ;true and the 2>/dev/null to see which one was the fastest. I guessed adding ;true would be slower because that’s actually adding a second script right? (I could be wrong). Anyway, while testing 2>/dev/null I encountered an error that I didn’t see yesterday. If 2>/dev/null finds files, it gives them back as an error. So the paths are the error message. I only tested it when it wouldn’t find files. This of course isn’t the best thing to return the founded files. Anyway, I guess I’ll have to go with ;true because it gives an “” when there’s nothing and it doesn’t give an error when files are found. I think it’s slightly slower though… But testing also verifies one important part, it continues on error :). But I also thought the other errors couldn’t be filtered. I could be wrong but I always thought that shell script errors in terminal have exit code 1.

Thanks

EDIT Testing speed between adding ;true or just not when I know there aren’t errors, repeating it 1000 times results in a difference of 1 second (;true is 1 seconds more than without) this can completely be explained by other variables like stuff running on the computer etc. although I turned everything off. Anyway, they’re equal in speed I think…

This kind of fixes my problem because I wasn’t hoping for the other errors to be filtered… It’d be good if they were but I didn’t think it was possible.

Thanks