Parenthesis in bash - subshell vs grouping
Asked Answered
N

1

6

In the manpage for bash, under the "Compound Commands" section, there are the following two entries:

(list) list is executed in a subshell environment (see COMMAND EXECUTION ENVIRONMENT below). Variable assignments and builtin commands that affect the shell's environment do not remain in effect after the command completes. The return status is the exit status of list.

and under test and [[:

( expression ) Returns the value of expression. This may be used to override the normal precedence of operators.

The only difference I can see is that in one, the parentheses have no spaces next to them, and in the other, they do. Is that what actually differentiates grouping vs a subshell, or is it dependent on the context?

In other words, if I run

if ! [ 2 -eq 2 ] || ( [ 2 -eq 2 ] && [ 4 -eq 4 ] ); then echo "hello"; fi

is this just grouping the conditions or running in a subshell?

Nucleonics answered 25/3, 2015 at 16:32 Comment(2)
As an aside, note that && has higher precedence than || so the parentheses aren't actually necessary in this case.Yingling
If you want grouping without a subshell, use { list; } -- a trailing semicolon or newline is required before the close brace.Primal
S
4

The context in question for those entries is relevant.

The latter is in the documentation for the [[ construct and is documenting the behavior of that construct on its arguments.

The former is discussing a top-level shell compound command construct (like the [[ construct itself) and introduces a sub-shell.

This comes up again in the description of the test/[ command later in the man page (but that is essentially just the same as the [[ discussion).

To do grouping within the current shell, you can use curly braces:

if ! [ 2 -eq 2 ] || { [ 2 -eq 2 ] && [ 4 -eq 4 ]; }; then
    ...
fi

(Note the spaces around the inside of the braces and the extra semicolon, which are both necessary.)

Spineless answered 25/3, 2015 at 16:35 Comment(2)
"The latter is in the documentation for the [[ construct..." Oops, I didn't notice that. So what happens when I do if ... ( someexpr ) as in the above, without the use of [[?Nucleonics
if (somexpr); then echo something; fi is someexpr in a sub-shell.Spineless

© 2022 - 2024 — McMap. All rights reserved.