Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

setting variables inside a compound command in bash fails (command group)

Tags:

bash

The group command { list; } should execute list in the current shell environment.

This allows things like variable assignments to be visible outside of the command group (http://mywiki.wooledge.org/BashGuide/CompoundCommands).

I use it to send output to a logfile as well as terminal:

{ { echo "Result is 13"; echo "ERROR: division by 0" 1>&2; } | tee -a stdout.txt; } 3>&1 1>&2 2>&3 | tee -a stderr.txt;

On the topic "pipe stdout and stderr to two different processes in shell script?" read here: pipe stdout and stderr to two different processes in shell script?.

{ echo "Result is 13"; echo "ERROR: division by 0" 1>&2; }

simulates a command with output to stdout and stderr.

I want to evaluate the exit status also. /bin/true and /bin/false simulate a command that may succeed or fail. So I try to save $? to a variable r:

~$ r=init; { /bin/true; r=$?; } | cat; echo $r;
init
~$ r=init; { /bin/true; r=$?; } 2>/dev/null; echo $r;
0

As you can see the above pipeline construct does not set variable r while the second command line leads to the expected result. Is it a bug or is it my fault? Thanks.

I tested Ubuntu 12.04.2 LTS (~$) and Debian GNU/Linux 7.0 (wheezy) (~#) with the following versions of bash:

~$ echo $BASH_VERSION
4.2.25(1)-release

~# echo $BASH_VERSION
4.2.37(1)-release
like image 793
Hagen Riedel Avatar asked Aug 02 '26 04:08

Hagen Riedel


1 Answers

I tried a test program:

x=0
{ x=$$ ; echo "$$ $BASHPID $x" ; }
echo $x

x=0
{ x=$$ ; echo "$$ $BASHPID $x" ; } | cat
echo $x

And indeed - it looks like the pipe forces the prior code into another process, but without reinitialising bash - so $BASHPID changes but $$ does.

See Difference between bash pid and $$ for more details of the different between $$ and $BASHPID.

Also outputting $BASH_SUBSHELL shows that the second bit is running in a subshell (level 1), and the first is at level 0.

like image 83
Douglas Leeder Avatar answered Aug 07 '26 03:08

Douglas Leeder



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!