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