【发布时间】:2015-03-04 07:31:01
【问题描述】:
通常,bash 函数定义使用花括号来包围主体:
foo()
{
...
}
今天在编写大量使用函数的 shell 脚本时,我遇到了在被调用函数中与调用函数中具有相同名称的变量的问题,即这些变量是相同的。然后我发现可以通过将函数内部的局部变量定义为局部变量来防止这种情况:local var=xyz。
然后,在某个时候,我发现了一个线程 (Defining bash function body using parenthesis instead of braces),其中解释说使用这样的括号定义函数同样有效:
foo()
(
...
)
这样做的效果是函数体在子shell中执行,这样做的好处是函数有自己的变量范围,这允许我在没有本地的情况下定义它们。由于拥有一个函数局部范围似乎比所有变量都是全局的更有意义并且更安全,所以我立即问自己:
- 为什么默认使用大括号而不是括号来包围函数体?
但是,我很快也发现了在子 shell 中执行函数的一个主要缺点,特别是从函数内部退出脚本不再起作用,而是迫使我在整个调用树中处理返回状态(在嵌套函数的情况下)。这让我想到了这个后续问题:
- 使用括号代替大括号是否还有其他主要缺点 (*)(这或许可以解释为什么大括号似乎更受欢迎)?
(*) 我知道(从我偶然发现的与异常相关的讨论中)有些人会争辩说,明确使用错误状态比能够从任何地方退出要好得多,但我更喜欢后者。
显然这两种风格各有优缺点。所以我希望你们中一些更有经验的 bash 用户能给我一些一般性的指导:
- 什么时候应该用花括号括住函数体,什么时候最好用括号?
编辑:答案要点
感谢您的回答,我现在对此有点清楚了。所以我从答案中得出的结论是:
-
坚持使用传统的花括号,如果只是为了不混淆脚本的潜在其他用户/开发者(如果整个正文都用括号括起来,甚至可以使用花括号)。
李> 花括号唯一真正的缺点是可以更改父作用域中的任何变量,尽管在某些情况下这可能是一个优点。这可以通过将变量声明为
local来轻松规避。另一方面,使用括号可能会产生一些严重的不良影响,例如弄乱退出、导致终止脚本出现问题以及隔离变量范围。
【问题讨论】:
标签: bash function parentheses curly-braces