Context:
I have a bash script (a wrapper for other scripts, really), that does the following pseudocode:
do a main function
if the main function returns:
$returncode = $? #most recent return code
if the main function runs longer than a timeout:
kill the main function
$returncode = 140 #the semi-canonical "exceeded allowed wall clock time" status
run a cleanup function
if the cleanup function returns an error: #nonzero return code
exit $? #exit the program with the status returned from the cleanup function
else #cleanup was successful
....
Question:
What should happen after the last line?
If the cleanup function was successful, but the main function was not, should my program return 0 (for the successful cleanup), or $returncode
, which contains the (possibly nonzero and unsuccessful) return code of the main function?
For a specific application, the answer would be easy: "it depends on what you need the script for."
However, this is more of a general/canonical question (and if this is the wrong place for it, kill it with fire): in Bash (or Linux in general) programming, do you typically want to return the status that "means" something (i.e. $returncode
) or do you ignore such subjectivities and simply return the code of the most recent function?
This isn't Bash-specific: if I have a standalone executable of any kind, how, canonically should it behave in these cases? Obviously, this is somewhat debatable. Even if there is a system for these things, I'm sure that a lot of people ignore it. All the same, I'd like to know.
Cheers!
Return the exit code from main. As the user of your script, I want to know if it did its job, not whether it cleaned up after failure. In fact, I expect programs/scripts clean up properly when they fail, so returning 0 would be misleading.
Lazily-written scripts just return with whatever exit code their last command happened to have. Well-written ones make sure to return a meaningful exit code.
By the way, my favorite way to ensure proper cleanup is to run a cleanup function on trap EXIT
.
WORKING_DIR=$(mktemp -d)
cleanUp() {
rm -rf "$WORKING_DIR"
}
# Run cleanUp() when the script exits, whether that's from a SIGTERM/SIGINT or
# just exiting normally.
trap cleanUp EXIT