Grouping teams in braces and pipelines does not save the variable

Say I have a myfile in the current working directory. I want to set a variable if the command runs normally, but also use its result.

 $ ls myfile && v=3 myfile $ echo "$v" 3 

But now I also want to pass the result, so I use the syntax { list; } { list; } for grouping commands:

  $ unset v
 $ {ls myfile && v = 3;  } |  grep myf
 myfile
 $ echo "$ v"
                   # v is not set

Bash help guide → 3.2.4.3 Grouping teams say:

 { list; } 

Placing a list of commands between curly braces results in a list of commands executed in the current shell context. No subshell is created. A semicolon (or new line) requires the following list.

So, as far as I understand, v should be set to 3. But this does not happen. Why?

+4
bash
source share
2 answers

These are not curly braces causing the creation of a subshell, this is a pipe.

To prove this:

 $ { ls && v=3; } > tmp $ echo "$v" 3 

To quote Greg :

In most shells, each pipeline command is executed in a separate SubShell.

+6
source share

You can use the BASH_SUBSHELL variable to check if you are in a subshell or not.

 # BASH_SUBSHELL will print level of subshell from top due to pipe { unset v && ls file && v=3 && echo "$BASH_SUBSHELL - $v"; } | nl 1 file 2 1 - 3 # outside BASH_SUBSHELL will print 0 echo "$BASH_SUBSHELL - $v"; 0 - 

You can use the piped command to print 1 , which means that it is in a subshell, so the value of v not accessible from the outside (obviously from the second output)

+3
source share

All Articles