0

In bash, are there any differences between opting to use ( ... ) or { ... }, as in my test case, both of these product the same expected result:

# using round brackets
(
    echo 'hello'
    echo 'world'
) | rev
# using squiggly brackets
{
    echo 'hello'
    echo 'world'
} | rev
# result:
olleh
dlrow

Perhaps this test case in a condition where they are the same, however are factors where I would opt for one syntax over the other?

balupton
  • 47,113
  • 32
  • 131
  • 182
  • Are you asking if there is a difference between `( )` `{ }` _in a pipeline_ ` | something`, or in general? – KamilCuk Nov 03 '21 at 06:47
  • both / in general — I've rephrased to try and make this more clear – balupton Nov 03 '21 at 06:48
  • 1
    Then https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#Command-Grouping would explain it for you? And https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#Pipelines – KamilCuk Nov 03 '21 at 06:50
  • Read the bash manual. – konsolebox Nov 03 '21 at 06:55
  • 1
    "_however are factors where I would opt for one syntax over the other_" - I use `( ... ) > result &` `pid=$!` if I want to start some heavy processing in the background while continuing the main flow. When I need the result, I can do `wait $pid` and then read `result`. Afaik, that's not possible with `{ ... }` - which if I'm correct usually gives a thread id back in `$!` that you can't `wait` for. – Ted Lyngmo Nov 03 '21 at 07:24
  • @TedLyngmo `Afaik, that's not possible with { ... }` could you give an example? There should be no difference... `{ sleep 5; } & wait $!` surely works. – KamilCuk Nov 03 '21 at 07:54
  • 1
    @KamilCuk You're correct. I used the wrong format. [shellcheck](https://www.shellcheck.net/) to the rescue (as always) :-) – Ted Lyngmo Nov 03 '21 at 08:55
  • 1
    Does this answer your question? [What are these scope changes in a bash script doing?](https://stackoverflow.com/a/69046250) – markp-fuso Nov 03 '21 at 13:36

1 Answers1

4

are there any differences between opting to use ( ... ) or { ... }

Yes, one spawns a subshell the other executes commands in current execution environment.

however are factors where I would opt for one syntax over the other?

Sure - use () when you want to spawn a subshell.

In bash, are there any differences between these two code blocks:

(I think, but I'm not 100% sure) that no. The left side of a pipeline is spawned in a subshell. Then Bash detects that (...) is a single only expression on the left side, so Bash optimizes and does not spawn a subshell and just executes the content of the second list of commands and does not spawn a second subshell, so both should result in exactly the same "count of subshell" being spawned. This is an "optimization", the same way ( ( ( ( ( ( echo ) ) ) ) ) ) can be just one subshell.

KamilCuk
  • 120,984
  • 8
  • 59
  • 111