Implicit return in bash functions?
return
does an explicit return from a shell function or "dot script" (a sourced script). If return
is not executed, an implicit return is made at the end of the shell function or dot script.
If return
is executed without a parameter, it is equivalent of returning the exit status of the most recently executed command.
That is how return
works in all POSIX shells.
For example,
gmx () {
echo 'foo'
return "$?"
}
is therefore equivalent to
gmx () {
echo 'foo'
return
}
which is the same as
gmx () {
echo 'foo'
}
In general, it is very seldom that you need to use $?
at all. It is really only needed if you need to save it for future use, for example if you need to investigate its value multiple times (in which case you would assign its value to a variable and perform a series of tests on that variable).
From the bash(1)
man page:
When executed, the exit status of a function is the exit status of the last command executed in the body.
I'll just add a few notes of caution to the answers already provided:
Even though
return
has a very special meaning to the shell, from a syntax point of view, it is a shell builtin command and a return statement is parsed like any other simple command. So, that means that like in the argument of any other command,$?
when unquoted, would be subject to split+globSo you need to quote that
$?
to avoid it:return "$?"
return
usually doesn't accept any option (ksh93
's accepts the usual--help
,--man
,--author
... though). The only argument it expects (optional) is the return code. The range of accepted return codes varies from shell to shell, and whether any value outside 0..255 is properly reflected in$?
also varies from shell to shell. See Default exit code when process is terminated? for details on that.Most shells accept negative numbers (after all, the argument passed to the
_exit()
/exitgroup()
system call is anint
, so with values encompassing at least -231 to 231-1, so it only makes sense that shells accept the same range for its functions).Most shells use the
waitpid()
and co. API to retrieve that exit status however in which case, it's truncated to a number between 0 and 255 when stored in$?
. Even though invoking a function does not involve spawning a process and usedwaitpid()
to retrieve its exit status as all is done in the same process, many shells also mimic thatwaitpid()
behaviour when invoking functions. Which means that even if you callreturn
with a negative value,$?
will contain a positive number.Now, among those shells whose
return
accepts negative numbers (ksh88, ksh93, bash, zsh, pdksh and derivatives other than mksh, yash), there are a few (pdksh and yash) which need it written asreturn -- -123
as otherwise that-123
is taken as three-1
,-2
,-3
invalid options.As pdksh and its derivatives (like OpenBSD
sh
orposh
) preserve the negative number in$?
, that means that doingreturn "$?"
would fail when$?
contains a negative number (which would happen when the last run command was a function that returned a negative number).So
return -- "$?"
would be better in those shells. However note that while supported by most shells, that syntax is not POSIX and in practice not supported bymksh
and ash derivatives.So, to sum up, with pdksh-based shells, you may use negative numbers in arguments to functions, but if you do,
return "$@"
won't work. In other shells,return "$@"
will work and you should avoid using negative numbers (or numbers outside of 0..255) as arguments toreturn
.In all shells that I know, calling
return
from inside a subshell running inside a function will cause the subshell to exit (with the provided exit status if any or that of the last command run), but will not otherwise cause a return from the function (to me, it's unclear whether POSIX gives you that warranty, some argue thatexit
should be used instead of exit subshells inside functions). For instancef() { (return 3) echo "still inside f. Exit status: $?" } f echo "f exit status: $?"
will output:
still inside f. Exit status: 3 f exit status: 0