bash函数:将主体括在括号和括号之间

问题描述 投票:27回答:4

通常,bash函数使用花括号将主体括起来来定义:

foo()
{
    ...
}

[今天在广泛使用函数的shell脚本中工作时,我遇到了与被调用函数中的名称与调用函数中的名称相同的变量的问题,即这些变量相同。然后,我发现可以通过将函数内部的局部变量定义为local来防止这种情况:local var=xyz

然后,在某个时候,我发现了一个线程(Defining bash function body using parenthesis instead of braces),其中解释为使用这样的括号定义函数同样有效:

foo()
(
    ...
)

这样做的结果是,函数主体是在子外壳中执行的,其好处是该函数具有自己的变量范围,这使我可以在不使用局部变量的情况下定义它们。由于具有局部函数范围似乎比全局所有变量更有意义并且更安全,所以我立即问自己:

  • 为什么默认情况下使用括号括住函数主体而不是括号?

但是,我很快也发现了在子shell中执行该函数的主要缺点,特别是从函数内部退出脚本不再起作用,而是迫使我在整个调用树中使用返回状态(在嵌套函数)。这使我想到了这个后续问题:

  • 使用括号而不是大括号还有其他主要缺点(*)(这可能解释了为什么似乎更喜欢使用大括号)?

(*)我知道(从我一段时间以来偶然发现的与异常相关的讨论中),有人会认为明确使用错误状态要比能够从任何地方退出要好得多,但是我更喜欢后者。

显然,两种样式都有其优点和缺点。因此,我希望一些较有经验的bash用户可以给我一些一般指导:

  • 我何时应使用花括号将函数主体括起来,以及何时建议切换到括号?

编辑:答案摘录

感谢您的回答,对此我的头脑现在更清楚了。所以我从答案中得到的是:

  • 粘上常规花括号,只是为了不使脚本的其他潜在用户/开发人员感到困惑(如果整个括号都括在括号中,甚至使用花括号)。

  • 花括号的唯一真正的缺点是,可以更改父作用域中的任何变量,尽管在某些情况下这可能是一个优点。可以通过将变量声明为local轻松避开此问题。

  • 另一方面,使用括号可能会产生一些严重的不良影响,例如弄乱出口,导致杀死脚本和隔离变量范围等问题。

bash function parentheses curly-braces
4个回答
16
投票

为什么默认情况下使用括号括住函数主体而不是括号?


5
投票

这真的很重要。由于bash函数不返回值并且它们使用的变量来自全局范围(也就是说,它们可以从其范围的“外部”访问变量),因此处理函数输出的常用方法是将值存储在一个变量,然后调用它。


4
投票

[当我想更改目录时,我倾向于使用子外壳,但是总是从同一原始目录开始,并且不麻烦使用pushd/popd或自己管理目录。


0
投票

注意:有时括号列表不在同一进程中运行:

© www.soinside.com 2019 - 2024. All rights reserved.