As @KamilCuk mentioned, the pipe from find to read in the loop means the exit occurs in a sub-shell. Which is to say, when you have find . -type f -print0 | <do some stuff>, and <do some stuff> includes a call to exit, that exit applies within the subshell created by the |. In the case of your script, myExit is calling exit which ends the while-loop on the right side of the pipe, but this does not end the parent shell in which traverse was actually running. traverse then finishes, date is executed 3 times, and the script ends.
Probably the easiest option is to use set -e at the top of your script. This is kind of a scortched earth approach: if anything returns non-zero, the script will exit.
To do this, replace the entire myExit function with this:
set -e
function myExit() {
echo "Exiting $1 ..."
return 1
}
Now you will get a non-zero return code when calling that function from inside the loop, and the script should exit immediately.
A more forgiving approach is to change myExit1 as above, but without adding set -e, and add a return 1 immediately after the call to myExit:
if [ "${#MD5_BASE}" -gt "$JOLIET_MAX" ]; then
myExit "[FAIL] Filename size ${#MD5_BASE} too long - $MD5_FILESPEC"
return 1
fi
And change the call to traverse to this:
if ! traverse; then exit; fi
Now when the if block ever fires, it will call myExit, which calls exit, which terminates the subshell, at which point traverse returns a value of 1, the if condition evaluates to true, and exit is called.
Another answer to your question suggests using process substitution, which is also good solution here. That shows the more typical pattern used for this type of loop operation:
while ... read ... ; do
...
done < (<input process>)
Finally, as matter of stylistic preference: I would probably get rid of myExit as a separate function, unless you have plans to expand it. As-is, it seems like it just creates unneeded complexity.
|- the right side of a pipe is in a subshell. Ex. tryecho | exit.echo|exit, you will see that it won't exit the bash either. You have to rewrite the logic of your script in a way that theexitis really done inside that process which you want to leave.