4

I have a bash script, where I call exit somewhere to skip the rest of the script when getopts doesn't recognize an option or doesn't find an expected option argument.

while getopts ":t:" opt; do
    case $opt in
        t)
            timelen="$OPTARG"
            ;;
        \?) printf "illegal option: -%s\n" "$OPTARG" >&2
            echo "$usage" >&2
            exit 1
            ;;
        :) printf "missing argument for -%s\n" "$OPTARG" >&2
           echo "$usage" >&2
           exit 1
           ;;
    esac
done

# reset of the script

I source the script in a bash shell. When something is wrong, the shell exits.

Is there some way other than exit to skip the rest of the script but without exiting the invoking shell?

Replacing exit with return doesn't work like for a function call, and the rest of the script will runs.

Thanks.

  • Hmm? return seems to work for me. If I have a script echo hello ; return ; echo there then source it I only get the hello output. – Stephen Harris Aug 2 '18 at 15:38
  • Thanks, @StephenHarris I made a mistake. I use exit inside a while loop. I guess replacing it with return only exits the while loop, but continue to run the rest of the program after the while loop. How can I skip the rest of the program then? – Tim Aug 2 '18 at 16:21
  • @Tim break exits a loop, return exits a function or a sourced script. – Kusalananda Aug 2 '18 at 16:24
  • @Tim, why do you source it instead of executing it? – glenn jackman Aug 2 '18 at 16:25
3

Use return.

The return bash builtin will exit the sourced script without stopping the calling (parent/sourcing) script.

From man bash:

return [n]
Causes a function to stop executing and return the value specified by n to its caller. If n is omitted, the return status is that of the last command executed in the function body. … If return is used outside a function, but during execution of a script by the . (source) command, it causes the shell to stop executing that script and return either n or the exit status of the last command executed within the script as the exit status of the script.

  • Thanks. Do return [n] and exit n work the same except in a function or a script being sourced? – Tim Aug 2 '18 at 17:01
  • No, a return is never an exit. An exit will "get out" of the running script (shell). A return will stop reading (and executing) either a sourced file or a function. A return outside a function and outside a sourced file will be reported as an error by bash. An exit (almost) never will be an error and will "stop all processing". @Tim – Isaac Aug 2 '18 at 17:06
2

You could simply wrap your script in a function and then use return the way you describe.

#!/bin/bash
main () {
    # Start of script
    if [ <condition> ]; then
        return
    fi
    # Rest of the script will not run if returned
}

main "$@"
1

return exits sourced scripts (and functions).

In your case:

while getopts ":t:" opt; do
    case $opt in
        t)
            timelen="$OPTARG"
            ;;
        \?) printf "illegal option: -%s\n" "$OPTARG" >&2
            echo "$usage" >&2
            return 1
            ;;
        :) printf "missing argument for -%s\n" "$OPTARG" >&2
           echo "$usage" >&2
           return 1
           ;;
    esac
done

Example test:

$ cat script1.sh
echo script1
source ./script2.sh
echo script1 ends
$ cat script2.sh
echo script2

while true; do
    return
done

echo script2 ends
$ bash script1.sh
script1
script2
script1 ends

Also sourcing script2.sh directly does the correct thing (without exiting from the current shell session):

$ source script2.sh
script2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.