Behavior of return statement in bash functions

In the date | while ... scenario, that while loop is executed in a subshell due to the presence of the pipe. Thus, the return statement breaks the loop and the subshell ends, leaving your function to carry on.

You'll have to reconstruct the code to remove the pipeline so that no subshells are created:

dostuff() {
    # redirect from a process substitution instead of a pipeline
    while true; do
        echo returning 0
        return 0
        echo really-notreached
    done < <(date)

    echo notreached
    return 3
}

If you return inside a function, that function will stop executing but the overall program will not exit.

If you exit inside a function, the overall program will exit.

You cannot return in the main body of a bash script, you can only return inside a function or sourced script.


For example:

#!/usr/bin/env bash

function doSomething {
    echo "a"
    return
    echo "b"  # this will not execute because it is after 'return'
}

function doSomethingElse {
    echo "d"
    exit 0
    echo "e"  # this will not execute because the program has exited
}

doSomething
echo "c"
doSomethingElse
echo "f"  # this will not execute because the program exited in 'doSomethingElse'

Running the above code will output:

a
c
d

But return should terminate a function call, not a subshell. exit is intended to terminate (sub)shell. I think, it's some undocumented bug/feature.

  • echo|return typed in commandline gives an error, that's correct - return should be in a function.
  • f(){ echo|return; } is accepted in the bash/dash, but return doesn't terminate a function call.

    If return terminates a subshell, it would work outside a function. So, conclusion is: return terminates a subshell in a function which is strange.