Bash: Return or exit?
From FVue
Contents
Problem
I want a shell script e.g. error.sh, to change the current directory when invoked interactive. But the script might also be called from another script. For example, consider these execution scenarios:
Scenario 1, called directly from command line
Source'd because for example, I want the script to change the current working directory:
source ./error.sh
Scenario 2, called from another script
#!/bin/bash
if ! ./error.sh; then
echo "Error occurred"
fi
The script can't use exit because this will kill the active process of scenario 1.
The script can't use return because you "can only `return' from a function or sourced script".
Solution
Don't use either return or exit directly, but indirectly return exit status of last command:
$(exit n)
Or even better, because you don't need a subshell:
true # $(exit 0) false # $(exit 1)
This satisfies both source'd and exec'ed scripts.
Journal
20060429
Trying return:
#!/bin/bash
#--- error.sh ------
cd ~/proj
return 1
. error.sh # Does work in scenario 1. But I always forget the . (source)
#+ before the script and the path-to-the-script, so I want an
#+ easier solution.
# Scenario 2 will also fail:
#+ ./error.sh: line 4: return: can only `return' from a
#+ function or sourced script
#!/bin/bash
if ! ./error.sh; then
echo "Error occurred"
fi
Trying exit:
# This doesn work in scenario 1, but fails scenario 2:
# When this script is sourced, it'll exit the main process
#!/bin/bash
#--- error.sh ------
cd ~/proj
exit 1
Solution:
# The solution? Don't specify either return or exit.
#+ Instead make use of Bash feature to return status of last command.
#!/bin/bash
#--- error.sh ------
cd ~/proj
$(exit 1)
# Wrapping the script in a function eases me :-)
function error() {
cd ~/error
. error.sh
}
# Combined with the function above, both scenarios are now satisfied:
error # Scenario 1: Changes current directory and returns error status.
# Scenario 2: Returns error status.
#!/bin/bash
if ! ./error.sh; then
echo "Error occurred"
fi
Advertisement