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.