difference between "function foo() {}" and "foo() {}"
The function
keyword was introduced in ksh. The traditional Bourne shell only had the foo ()
syntax, and POSIX standardizes only the foo ()
syntax.
In ATT ksh (but not pdksh), there are a few differences between functions defined by function
and functions defined with the Bourne/POSIX syntax. In functions defined by function
, the typeset
keyword declares a local variable: once the function exits, the value of the variable is reset to what it was before entering the function. With the classic syntax, variables have a global scope whether you use typeset
or not.
$ ksh -c 'a=global; f () { typeset a=local; }; f; echo $a'
local
$ ksh -c 'a=global; function f { typeset a=local; }; f; echo $a'
global
Another difference in ksh is that functions defined with the function
keyword have their own trap context. Traps defined outside the function are ignored while executing the function, and fatal errors inside the function exit only the function and not from the whole script. Also, $0
is the function name in a function defined by function
but the script name in a function defined with ()
.
Pdksh does not emulate ATT ksh. In pdksh, typeset
creates locally-scoped variables regardless of the function, and there are no local traps (though using function
does make some minor differences — see the man page for details).
Bash and zsh introduced the function
keyword for compatibility with ksh. However in these shells function foo { … }
and foo () { … }
are strictly identical, as is the bash and zsh extension function foo () { … }
. The typeset
keyword always declares local variables (except with -g
of course), and traps are not local (you can get local traps in zsh by setting the local_traps
option).
There is no difference AFAIK, other than the fact that the second version is more portable.
foo() any-command
is the Bourne syntax supported by any Bourne-like shell but bash
, yash
and recent versions of posh
(which only support compound commands). (the Bourne shell and AT&T implementations of ksh
don't support foo() any-command > redirections
unless any-command
is a compound command though).
foo() any-compound-command
(examples of compound commands: { cmd; }
, for i do echo "$i"; done
, (cmd)
... the most commonly used being { ...; }
)
is the POSIX syntax supported by any Bourne-like shell and the one you generally want to use.
function foo { ...; }
is the Korn shell syntax, which predates the Bourne syntax. Only use this one if writing specifically for the AT&T implementation of the Korn shell and need the specific treatment it receives there. That syntax is not POSIX, but is supported by bash
, yash
and zsh
for compatibility with the Korn shell though those shells (and the pdksh
-based variants of the Korn shell) don't treat it any different from the standard syntax.
function foo () { ...; }
is the syntax of no shell and should not be used. It only happens to be supported by accident by bash
, yash
, zsh
and the pdksh
based variants of the Korn shell. Incidentally, it's also the awk
function syntax.
If we continue going down the esoteric list,
function foo() other-compound-command
(like function foo() (subshell)
or function foo() for i do; ... done
) is even worse. It is supported by bash
, yash
and zsh
, but not ksh, even the pdksh
-based variants.
While:
function foo() simple command
is only supported by zsh
.