我应该将shell函数定义为函数x()还是x()?

时间:2014-03-06 23:00:43

标签: bash shell sh

我注意到有三种方法可以定义shell函数,我从未在任何地方看到它的解释。

# Option 1
function log(){

}

# Option 2
log(){

}

# Option 3, added due to answers
function log{

}

这三个定义之间有不同之处吗?他们的行为是不同的,还是只是外表?

是否应该使用哪种标准?我希望第一个选项更可取,因为我想它可以消除某些地方的模糊性。

提前致谢!

在回答后编辑:投票结束为“基于意见”的人;我询问了行为上的差异,而不仅仅是为什么人们认为我应该使用哪种行为。事实上,只有Bash支持一个,这意味着每个人都应该使用第二个选项。

6 个答案:

答案 0 :(得分:11)

log() 
Bourne Shell系列支持

和任何类型的派生(破折号,yash) 是POSIX std语法,可能是您想用来编写与旧系统兼容的东西的语法。可能是你想要使用的那个。

function log () { ...; }

bash和zsh支持但是同时使用function ()只是错误的,应该避免使用。

function log { ...; }

是否为Korn Shell语法,并且出于兼容性原因受bash和zsh支持,但不是POSIX

http://wiki.bash-hackers.org/scripting/obsolete关于“function log()”

的引用

这是Korn和POSIX样式函数定义之间的合并 - 使用函数关键字和括号。它没有用处,没有历史基础或理由存在。它没有由POSIX指定。它被Bash,mksh,zsh和其他一些Korn shell所接受,它被视为与POSIX风格的函数相同。它不被AT& T ksh接受。永远不应该使用它。请参阅下表中的function关键字。 Bash没有将此功能记录为明确弃用。

答案 1 :(得分:7)

选项1和3的缺点是它们都是所谓的"bashisms"。如果您想要跨shell兼容性(例如,在* BSD中使用sh),请使用选项2,因为任何POSIX shell都必须支持它。

答案 2 :(得分:6)

一点历史

对于绝对Bourne shell和POSIX兼容性,请使用log () { ...; }。这在较旧的unix系统和小型Linux发行版中尤其重要,这些发行版往往包含最少的shell实现。

David Korn引入function关键字有一个特殊原因。他想补充一下 ksh(ksh93)中函数的特性,希望明确区分正常函数和增强函数。

ksh93中,使用function name { ...; }定义的函数可以使用局部变量(如果它们的话) 用typeset var=value声明。

Bash使用关键字declarelocal,而afaik可以在两种类型的函数中使用。即使typeset也是declare的同义词。

混合语法function ()与Bourne,ksh或POSIX都不兼容。


在我自己的ksh代码中,我倾向于使用大量函数,而局部变量往往会改进代码。 如果我希望代码在比ksh93更通用的shell中重用,我将恢复为POSIX样式函数并使用子shell强制变量为本地。

答案 3 :(得分:2)

根据Bash Hackers Wiki,function关键字是无用的,不应该使用,因为它不可移植。显然,只有bash和其他ksh派生的shell允许这两者,而function关键字现在已经过时了回到ksh风格的函数。以下参考资料给出了更好的解释:

http://wiki.bash-hackers.org/scripting/obsolete

http://www.gnu.org/software/bash/manual/bashref.html#Shell-Functions

http://tldp.org/LDP/abs/html/functions.html

答案 4 :(得分:1)

这只是你个人的电话,因为两种语法都可以正常工作。但是这一个:

log() {
    echo "logs"
}

是最初的Bourne和MODERN POSIX语法。

答案 5 :(得分:1)

存在很大差异:可移植性function关键字不是POSIX,仅受bashksh支持。