3

In a bash script, I have a function that does some processing on the argument passed to it. I'd like to set a return value depending on how the processing went. Problem is that the function is called from find ... -exec bash -c func and thus losing the chance of updating a global variable that way, like error_code.

#!/bin/bash
check_file() {
    filename=$1
    echo -n "$filename ... "
    if [ ... ]; then
        echo "NOK"
# return/update error_code?
    else
        echo "OK"
    fi
}

export -f check_file
# look for exec binary only
find . -type f -executable -exec bash -c "file -i {} | grep -q 'application/x-executable; charset=binary'" \; -exec bash -c 'check_file "$0"' {} \;
# exit $error_code??

In case error_code were a global variable that the function can update, it would then update it only when processing is 'NOK', as find will call many times the function check_file.

How can I do this with the existing script or perhaps need a different approach?

  • Find doesn't preserve the return value from an -exec (aside from treating 0 as true and anything else as false), so if you want anything more granular than that you'll need to produce it as output, either writing it to a file or stdout or stderr, and examine it after find finishes. – Mark Plotnick Jul 16 '15 at 15:48
  • That's the point where you should switch from find ... -exec ... to find ... | while read .... – lcd047 Jul 16 '15 at 18:40
  • @lcd047 be it -exec or | while read that will spawn another shell and the problem remains – fduff Jul 17 '15 at 7:32
  • Nope, with find ... | while read ... you don't have to spawn a shell for each file. – lcd047 Jul 17 '15 at 8:50
  • This is what kill is for. – mikeserv Jul 17 '15 at 8:54
1

I got the script to do what I wanted, it's not the most elegant solution but it does the job.

The main shell creates a temp file, exports its name to subsequent subshells, which can write to it. The main shell then at the end reads the return code, deletes the temp file and returns the error code value.

#!/bin/bash
export tmpf=`mktemp`
rcode=0
echo $rcode > $tmpf
...

check_file() {
...
echo 1 > $tmpf
...
}
...
rcode=`cat $tmpf`
rm -f $tmpf
echo "done."
exit $rcode

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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