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"
fi
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; macOS is stuck at version 3.x so you'd have to install it from a port collection. 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
Beware that in bash 4.0 through 4.2, this works but traverses symbolic links to directories, which is usually not desirable.
If you use zsh instead of bash, recursive globbing works out of the box with no gotchas. Zsh is available by default on OSX/macOS. In zsh, you can just write
set -e
for x in **/*.xml; do invalid_command "$x"; done
The first problem can be solved by exporting the path inside the do shell script part:
tell application "Finder"
activate
choose file
set myFile to result as text
end tell
do shell script "export MYFILE=" & quoted form of myFile & " ; /Users/user_name/bin/sh/echo_var_myfile.sh"
In my example "echo_var_myfile.sh" is
#!/bin/bash
echo $MYFILE >> /Users/user_name/echo_var_myfile.txt
The executable bit has to be set:
chmod +x /Users/user_name/bin/sh/echo_var_myfile.sh
The result is the path to the chosen file.
You mustn't add a second do shell script for the shell script because as soon as the first one runs it dies and no values are exported.
Best Answer
will give you the device the file is on. To combine this directly with
diskutil info
use