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)中,由functionBourne/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 > redirectionsany-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(以及pdkshKorn shell的基于 的变体)不会将其与标准语法区别对待。
function foo () { ...; }
Run Code Online (Sandbox Code Playgroud)
是no shell的语法,不应使用。它只是碰巧偶然的支持bash,yash,zsh和pdkshKorn 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不使用关键字(尽管它被保留)。
| 归档时间: |
|
| 查看次数: |
36125 次 |
| 最近记录: |