Reputation: 4394
If my script gets sourced with
. ./my_script.sh
source ./my_script.sh
then to stop execution in the script, I would use return
.
If my script is directly executed with
./my_script.sh
bash ./my_script.sh
then I'd insert an exit
.
If I don't know whether the user will source it or directly execute it, how can I cleanly stop the script without killing the terminal it was called from?
Preferably, the code snippet should be able to terminate the script even if it were placed inside one of the script's functions.
Upvotes: 3
Views: 2999
Reputation: 206617
Here's one way to find out which method was used to invoke the script.
if [[ "$0" == "bash" ]]; then
echo "source 'file' was used"
else
echo "bash 'file' was used"
fi
Update, In response to comment by @mklement0:
If your script is named my_script.sh
, you can use
b=$(basename "$0")
if [[ "$b" == "my_script.sh" ]]; then
echo "bash 'file' was used"
else
echo "source 'file' was used"
fi
Upvotes: 1
Reputation: 438153
Try the following:
ec=0 # determine the desired exit code
return $ec 2>/dev/null || exit $ec
return
will succeed if the script is being sourced, otherwise exit
will kick in. The 2>/dev/null
suppresses the error message in case the script is not sourced.
The net effect is that the script will terminate with the desired exit / return code, regardless of whether it was sourced or not.
Update: The OP wants to be able to exit the script from inside a function within the script.
The only way I can think of is to place all of your script's code in a subshell and call exit
from inside the functions inside that subshell; then place the return 2>/dev/null || exit
command after the subshell (as the only statement outside the subshell):
#!/usr/bin/env bash
( # subshell to place all code in
foo() {
exit 1 # exit the subshell
}
foo # invoke the function
)
# Terminate script with exit code from subshell.
ec=$?; return $ec 2>/dev/null || exit $ec
Upvotes: 7