Car*_*rós 120 shell bash posix function
我可以bash
使用或省略function
关键字来定义函数。有什么区别吗?
#!/bin/bash
function foo() {
echo "foo"
}
bar() {
echo "bar"
}
foo
bar
Run Code Online (Sandbox Code Playgroud)
这两个函数调用foo
和bar
成功,我看不出有什么区别。所以我想知道它是否只是为了提高可读性,或者我遗漏了什么......
顺便说一句,在其他 shell 中,例如dash
(在 debian/ubuntu 中/bin/sh
符号链接dash
)它在使用function
关键字时失败。
Gil*_*il' 114
该function
关键字年推出的KSH。传统的Bourne shell只有foo ()
语法,而POSIX只标准化了foo ()
语法。
在 ATT ksh(但不是 pdksh)中,由function
Bourne/POSIX 语法定义的函数和用 Bourne/POSIX 语法定义的函数之间存在一些差异。在由 定义的函数中function
,typeset
关键字声明了一个局部变量:一旦函数退出,变量的值将重置为进入函数之前的值。使用经典语法,无论您是否使用,变量都具有全局作用域typeset
。
$ 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
Run Code Online (Sandbox Code Playgroud)
ksh 的另一个区别是用function
关键字定义的函数有自己的陷阱上下文。函数外部定义的陷阱在执行函数时会被忽略,函数内部的致命错误仅退出函数而不是整个脚本。此外,$0
是由 定义的函数中的函数名称,function
而是由()
.
Pdksh 不模拟 ATT ksh。在 pdksh 中,typeset
无论函数如何,都会创建局部作用域的变量,并且没有局部陷阱(尽管使用function
确实会产生一些细微的差异 - 有关详细信息,请参阅手册页)。
Bash 和 zsh 引入了function
与 ksh 兼容的关键字。但是,在这些 shell 中function foo { … }
和foo () { … }
严格相同,bash 和 zsh 扩展名也是如此function foo () { … }
。该typeset
关键字总是声明局部变量(除了-g
当然的),和陷阱是不是本地的(你可以通过设置获得的zsh本地陷阱local_traps
选项)。
sch*_*iba 54
除了第二个版本更便携这一事实之外,AFAIK 没有区别。
Sté*_*las 41
foo() any-command
Run Code Online (Sandbox Code Playgroud)
是由支撑在伯恩语法任何类似Bourne壳但是bash
,yash
和的最新版本posh
(其仅支持化合物命令)。(除非是复合命令,否则Bourne shell 和 AT&T 实现ksh
不支持)。foo() any-command > redirections
any-command
foo() any-compound-command
Run Code Online (Sandbox Code Playgroud)
(复合命令的例子:{ cmd; }
, for i do echo "$i"; done
, (cmd)
... 最常用的是{ ...; }
)
是任何类似 Bourne 的 shell 都支持的 POSIX 语法,也是您通常想要使用的语法。
function foo { ...; }
Run Code Online (Sandbox Code Playgroud)
是 Korn shell 语法,它早于 Bourne 语法。只有在专门为 Korn shell 的 AT&T 实现编写并且需要它在那里接受的特定处理时才使用这个。该语法不是 POSIX,但受bash
,支持,yash
并且zsh
为了与 Korn shell 兼容,尽管这些 shell(以及pdksh
Korn shell的基于 的变体)不会将其与标准语法区别对待。
function foo () { ...; }
Run Code Online (Sandbox Code Playgroud)
是no shell的语法,不应使用。它只是碰巧偶然的支持bash
,yash
,zsh
和pdksh
Korn shell中的基础变种。顺便说一句,这也是awk
函数语法。
如果我们继续沿着深奥的列表,
function foo() other-compound-command
Run Code Online (Sandbox Code Playgroud)
(如function foo() (subshell)
或function foo() for i do; ... done
)甚至更糟。它受bash
,yash
和支持zsh
,但不支持 ksh,甚至是pdksh
基于 - 的变体。
尽管:
function foo() simple command
Run Code Online (Sandbox Code Playgroud)
仅支持zsh
.
dep*_*uid 23
在语义上,这两种形式在 Bash 中是等价的。
从手册页:
Shell 函数声明如下:
Run Code Online (Sandbox Code Playgroud)name () compound-command [redirection] function name [()] compound-command [redirection]
这定义了一个名为
name
. 保留字功能是可选的。如果提供了函数保留字,则括号是可选的。
编辑:我刚刚注意到这个问题被标记为posix
。在 POSIX 中sh
,function
不使用关键字(尽管它被保留)。