bash的功能:封闭身在大括号与括号 [英] bash functions: enclosing the body in braces vs. parentheses

查看:155
本文介绍了bash的功能:封闭身在大括号与括号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

一般情况下,bash的功能是用花括号括身体定义的:

 富()
{
    ...
}

这是一个shell脚本,今天大量使用的功能工作时,我碰到的问题,在称为调用函数具有相同的名称,即这些变量是相同的变量。然后我发现了,这可能是通过定义函数里面地方局部变量pvented $ P $:局部变量= XYZ

然后,在某些时候,我发现一个线程(<一个href=\"http://stackoverflow.com/questions/14651980/defining-bash-function-body-using-parenthesis-instead-of-braces\">Defining使用括号代替括号的)bash函数体中是这样解释的,它只是为有效来定义使用括号这样的功能:

 富()

    ...

这样做的效果是,函数体在子shell,它具有的好处是功能都有自己的变量范围,这让我确定他们没有本地执行。由于具有功能本地范围似乎使更多的意义,并要安全得多比所有的变量是全球性的,我马上问自己:


  • 为什么默认情况下用于封装函数体来代替括号括号?

不过,我很快也发现了一个重大的缺点在子shell执行的功能,特别是从一个函数内部退出脚本不工作了,而不是强迫我沿着整个调用树的返回状态(工作在嵌套函数的情况下)。这使我这个跟进的问题:


  • 是否有其他重大负面影响(*)来使用圆括号,而不是括号(这或许可以解释为什么括号似乎是preferred)?

(*)我知道(在异常相关的讨论,我在一段时间内绊倒),有些会明确使用错误状态认为是比能够从任何地方退出好多了,但我preFER后者。

显然,这两种风格都有其优点和缺点。所以我希望你们中的一些有经验的bash用户可以给我一些一般性的指导:


  • 我什么时候用花括号括函数体,并且是当它建议切换到括号?

编辑:从答案外卖

谢谢您的回答,我的头现在的问候更清楚一点。所以,我从答案带走的是:


  • 坚持常规大括号,如果只是为了不混淆潜在的其他用户/开发者的脚本(甚至使用括号如果全身被包裹在括号中)。


  • 大括号的唯一真正的缺点是,在父范围的任何变量是可以改变的,虽然在某些情况下,这可能是一个优点。这很容易通过声明变量作为规避本地


  • 使用括号,而另一方面,可能有一些严重的不良影响,如搞乱了出口,导致问题杀死一个脚本,和隔离的变量范围。



解决方案

  

为什么默认情况下用于封装函数体来代替括号括号?


函数的主体可以是任何复合命令。这通常是 {名单; } ,但其他三种形​​式的复合命令在技术上允许的:(列表)((如pression )) [EX pression]

C和在C家人喜欢C ++,Java和C#和JavaScript的所有语言使用花括号来分隔函数体。大括号是熟悉这些语言的程序员最自然的语法。


  

还有没有其他的重大负面影响(*)来使用圆括号,而不是括号(这或许可以解释为什么括号似乎是preferred)?


是的。有许多事情你不能从一个子壳做的,其中包括:


  • 更改全局变量。变量的变化将不会传播到父shell。

  • 退出脚本。一个退出语句将退出只子shell。

启动子壳也可能是一个严重的性能损失。你推出每次调用函数时一个新的进程。

您也可以,如果你的脚本被杀害得到怪异的行为。家长和孩子的炮弹接收信号会发生变化。这是一个微妙的影响,但如果你有陷阱处理程序,或者你脚本的部分不工作,你想要的方式。


  我

当必须使用大括号括函数体,并且是当它建议切换到括号?


我劝你总是使用大括号内。如果你想要一个明确的子shell,再加入一组括号花括号内。只用括号中极不寻常的语法和会混淆很多人读你的脚本。

 富(){
   (
       子shell命令;
   )
}

Usually, bash functions are defined using curly braces to enclose the body:

foo()
{
    ...
}

When working on a shell script today making extensive use of functions, I've run into problems with variables that have the same name in the called as in the calling function, namely that those variables are the same. I've then found out that this can be prevented by defining the local variables inside the function as local: local var=xyz.

Then, at some point, I've discovered a thread (Defining bash function body using parenthesis instead of braces) in which it is explained that it's just as valid to define a function using parentheses like this:

foo()
(
    ...
)

The effect of this is that the function body is executed in a subshell, which has the benefit that the function has its own variable scope, which allows me to define them without local. Since having a function-local scope seems to make much more sense and to be much safer than all variables being global, I immediately ask myself:

  • Why are braces used by default to enclose the function body instead of parentheses?

However, I quickly also discovered a major downside to executing the function in a subshell, specifically that exiting the script from inside a function doesn't work anymore, instead forcing me to work with the return status along the whole call tree (in case of nested functions). This leads me to this follow-up question:

  • Are there other major downsides (*) to using parentheses instead of braces (which might explain why braces seem to be preferred)?

(*) I'm aware (from exception-related discussions I've stumbled upon over time) that some would argue that explicitly using the error status is much better than being able to exit from anywhere, but I prefer the latter.

Apparently both styles have their advantages and disadvantages. So I hope some of you more experienced bash users can give me some general guidance:

  • When shall I use curly braces to enclose the function body, and when is it advisable to switch to parentheses?

EDIT: Take-aways from the answers

Thanks for your answers, my head's now a bit clearer with regards to this. So what I take away from the answers is:

  • Stick to the conventional curly braces, if only in order not to confuse potential other users/developers of the script (and even use the braces if the whole body is wrapped in parentheses).

  • The only real disadvantage of the curly braces is that any variable in the parent scope can be changed, although in some situations this might be an advantage. This can easily be circumvented by declaring the variables as local.

  • Using parentheses, on the other hand, might have some serious unwanted effects, such as messing up exits, leading to problems with killing a script, and isolating the variable scope.

解决方案

Why are braces used by default to enclose the function body instead of parentheses?

The body of a function can be any compound command. This is typically { list; }, but three other forms of compound commands are technically allowed: (list), ((expression)), and [[ expression ]].

C and languages in the C family like C++, Java, C#, and JavaScript all use curly braces to delimit function bodies. Curly braces are the most natural syntax for programmers familiar with those languages.

Are there other major downsides (*) to using parentheses instead of braces (which might explain why braces seem to be preferred)?

Yes. There are numerous things you can't do from a sub-shell, including:

  • Change global variables. Variables changes will not propagate to the parent shell.
  • Exit the script. An exit statement will exit only the sub-shell.

Starting a sub-shell can also be a serious performance hit. You're launching a new process each time you call the function.

You might also get weird behavior if your script is killed. The signals the parent and child shells receive will change. It's a subtle effect but if you have trap handlers or you kill your script those parts not work the way you want.

When shall I use curly braces to enclose the function body, and when is it advisable to switch to parentheses?

I would advise you to always use curly braces. If you want an explicit sub-shell, then add a set of parentheses inside the curly braces. Using just parentheses is highly unusual syntax and would confuse many people reading your script.

foo() {
   (
       subshell commands;
   )
}

这篇关于bash的功能:封闭身在大括号与括号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆