问题
This script demonstrates defining a bash function with parenthesis verses with braces. The parenthesis have the nice effect of making environment variables created in the function "local", I guess because the function body is executed as a sub-shell. The output is:
A=something
A=
B=something
B=something
The question is if this is allowed syntax for defining a function.
#!/bin/bash
foo() (
export A=something
echo A=$A
)
bar() {
export B=something
echo B=$B
}
foo
echo A=$A
bar
echo B=$B
回答1:
Yes, that syntax is allowed. As described in the bash man page, the definition of a bash function is:
[ function ] name () compound-command [redirection]
Some more description (also from the man page):
The body of the function is the compound command
compound-command
. That command is usually a list of commands between{
and}
, but may be any command listed under Compound Commands above.
()
and {}
enclosed lists are compound commands. The full list (again from the man page, just edited down to a simple list):
A compound command is one of the following:
(list) { list; } ((expression)) [[expression]] for name [ in word ] ; do list ; done for (( expr1 ; expr2 ; expr3 )) ; do list ; done select name [ in word ] ; do list ; done case word in [ [(] pattern [ | pattern ] ... ) list ;; ] ... esac if list; then list; [ elif list; then list; ] ... [ else list; ] fi while list; do list; done until list; do list; done
回答2:
Both are valid, and as Carl mentioned any compound command can also be used, e.g.:
$ f() if [ "$1" = 'a' ]; then echo 'equals a'; fi
$ f a
equals a
$ f b
$
POSIX 7 2.9.5 Function Definition Command http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_09_05:
The format of a function definition command is as follows:
fname() compound-command[io-redirect ...]
[...] The argument compound-command represents a compound command, as described in Compound Commands.
Then 2.9.4 Compound Commands http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_09_04:
(compound-list) [...] Variable assignments and built-in commands that affect the environment shall not remain in effect after the list finishes.
{ compound-list;} Execute compound-list in the current process environment.
The semantics are the same as using ()
without a function definition: it does not create a new process, but gets executed in what POSIX and Bash call a "subshell environment".
来源:https://stackoverflow.com/questions/14651980/defining-bash-function-body-using-parenthesis-instead-of-braces