Reputation: 99
I'm fairly new to bash scripting. I have 4 nested bash scripts, and i'm having trouble propogating the error from the 4th script appropriately. eg:
script1.sh:
source script2.sh
<check for error and display appropriate message>
script2.sh:
source script3.sh param_1
<return to script1 on error>
source script3.sh param_2
<return to script1 on error>
source script3.sh param_n
<return to script1 on error>
script3.sh
<some processing>
script4.sh
echo "this statement is not reached"
return $?
script4.sh
<some processing>
exit $?
My requirements are:
This thread talked about using the return statement to return from a sourced bash script, but as script4 is executed i need to exit. I don't understand why the exit statement in script4 causes both the original shell and the sub shell to terminate? Surely it should only exit the sub shell?
Do i need to look at signals and traps?
Thanks for any help
Upvotes: 3
Views: 3998
Reputation: 295443
Best practice is to be explicit. If your code is always going to be sourced, and thus return
will be valid, simply::
source foo || return
return
uses the exit status of the immediately prior command as its default value, so there's no need to capture and then pass it through.
If you don't know if you'll be sourced or executed, this gets a bit more complicated:
source foo || { rc=$?; return "$rc" 2>/dev/null || exit "$rc" }
Upvotes: 3
Reputation: 246827
You can keep set -e
enabled if you want. Then you'll have to be more careful about invoking a script where you know the exit status may be non-zero:
script3.sh
<some processing>
if script4.sh; then
rc=0
else
rc=$?
fi
echo "script4 complete"
return $rc
See https://www.gnu.org/software/bash/manual/bashref.html#index-set
IMO, using set -e
is appropriate if you truly want to abort your program for any error. Here, where you want to <check for error and display appropriate message>
, that's clearly not the case.
Upvotes: 4