9

这个脚本演示了用括号和大括号定义一个 bash 函数。括号具有在函数“本地”中创建环境变量的良好效果,我猜是因为函数体是作为子外壳执行的。输出是:

A=something
A=
B=something
B=something

问题是这是否是定义函数的允许语法。

#!/bin/bash

foo() (
    export A=something
    echo A=$A
)

bar() {
    export B=something
    echo B=$B
}

foo
echo A=$A
bar
echo B=$B
4

2 回答 2

11

是的,该语法是允许的。如bash手册页所述,bash 函数的定义是:

[ function ] name () compound-command [redirection]

更多描述(也来自手册页):

函数的主体是复合命令compound-command。该命令通常是 和 之间的命令列表{}但可以是上面的复合命令下列出的任何命令。

(){}封闭的列表是复合命令。完整列表(同样来自手册页,只是编辑为一个简单列表):

复合命令是以下之一:

(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
于 2013-02-01T17:44:13.807 回答
4

两者都是有效的,正如 Carl 提到的,也可以使用任何复合命令,例如:

$ f() if [ "$1" = 'a' ]; then echo 'equals a'; fi
$ f a
equals a
$ f b
$

POSIX 7 2.9.5 函数定义命令 http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_09_05

函数定义命令的格式如下:

fname() 复合命令[io-redirect ...]

[...] 参数 Compound-command 表示复合命令,如复合命令中所述。

然后是 2.9.4 复合命令 http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_09_04

(compound-list) [...] 影响环境的变量分配和内置命令在列表完成后将不再有效。

{ Compound-list;} 在当前流程环境中执行复合列表。

语义与()不使用函数定义相同:它不会创建新进程,而是在 POSIX 和 Bash 所谓的“子shell 环境”中执行。

于 2015-07-09T11:11:36.363 回答