Answers:
()
,语法实际上将是模棱两可的。定义函数必须有一些明确的语法,并且在没有实质性改变其他 Shell语法的情况下,它不能是这样的:
do_something {
# one or more commands go here
}
您说过“这与当前语法不冲突”,但确实如此!请注意,尝试运行该语法的第一行时,不会出现任何语法错误。您会得到一个错误,但这不是关于语法的错误。第二行带有}
,是语法错误,但第一行不是。而是do_something {
尝试运行一个名为的命令do_something
并将其{
作为参数传递给该命令:
$ do_something {
do_something: command not found
如果已经有一个名为的命令do_something
,那么您正在运行它。如果已经有一个调用的函数do_something
,则说明您正在调用它。通常,语法要明确,这很重要,但是特别重要的是,可以重新定义函数而不会意外调用它。定义函数并调用它应该看起来不一样。
{
和处理(
。就像type {
您会说的那样,它{
是一个shell关键字。这样就好了[[
。如果在原本可能是命令的情况下使用,则{
带有特殊的语义。具体来说,它执行命令分组。但是,在其他情况下,可以不转义使用它来表示文字{
字符。这包括将其作为命令的第二个或后续单词传递的情况。
当然,Bash 可能被设计为{
与当前有所不同。但是,它的语法将不再与POSIX Shell兼容,并且Bash不会真正成为Bourne风格的Shell,并且将无法运行许多Shell脚本。
相反,(
是一个外壳元字符。它始终是经过特殊处理的,如果它出现在一个命令,而不是引用(与'
'
,"
"
或\
)。因此,语法没有歧义:
do_something() {
# one or more commands go here
}
那没什么别的了。如果Bash没有函数,那么这将是语法错误,因为同样的原因echo foo(bar)
是语法错误。
如果您真的不喜欢这种()
表示法,则可以使用关键字function
并忽略它,如sudodus所述。请注意,这并不是大多数其他Bourne样式的shell中定义函数的语法的一部分-在某些情况下,它受支持,但是以这种方式定义的函数具有不同的语义 -因此使用该脚本的脚本将不可移植。(此语法能够明确的原因是,function
它本身是Bash中的关键字,表示紧随其后的是函数定义的开始。)
最后,请注意,尽管大多数函数定义都{
在实践中使用,但允许使用任何复合命令。如果您的函数的主体始终希望在子外壳中运行,则可以使用(
)
而不是{
}
。
该()
令牌是告诉shell解释你是声明功能。
$ do_something () { echo 'do it'; } ; do_something
do it
的替代方法bash
是function
function do_something {
echo 'do it'
}
或单线测试
$ bash -c "function do_something { echo 'do it'; } ; do_something"
do it
function
关键字是预先POSIX KSH主义该bash的支撑件的向后兼容性; 但是,bash对它的支持很差(不会像在旧版ksh中以该形式声明的函数那样将变量设置为局部函数默认值)。因此,它对于新代码不是理想的。参见wiki.bash-hackers.org/scripting/obsolete
您真是个真正的括号风格的主义者!
考虑其他完美的花括号样式:
foo
{
...
}
foo
{
...
}
foo
while ...; do ...; done # Look, ma! No braces!
foo
( ... ) # Look, ma! No braces and a subshell to boot!
Shell如何分辨这些是函数定义,而不仅仅是命令foo
和命令列表?在所有这些情况下,都需要一个附加的歧义因素,例如()
或function
关键字。
()
或类似的东西。