Home > Back-end >  Assigning values by doing multiple commands per bash test statement not work
Assigning values by doing multiple commands per bash test statement not work

Time:09-22

When I want to issue multiple command by using bash test statement with subshell, this works:

a=255
 b=0
 [[ a -eq 255 ]] && ( echo $a;echo $b )
255
0

But why assign values not work?

[[ a -eq 255 ]] && ( a=0;b=255 )
 echo $a
255

 echo $b
0

I know if I change the parenthesis to bracket, it works, and I just want to know why it doesn't work when assigning values.

CodePudding user response:

First of all, take a look at the man bash:

Placing a list of commands between parentheses causes a subshell environment to be created (see Command Execution Environment), and each of the commands in list to be executed in that subshell. Since the list is executed in a subshell, variable assignments do not remain in effect after the subshell completes.

When subshell's executed it creates its own set of variables that are not visible to any other shell, but { list; } is executed in the current shell, so these variables are visible, you can make sure using declare built-in command:

echo "spawn a subshell"
( (declare sub_local=100; declare -p | grep sub_local) )

echo "current shell"
declare -p | grep sub_local

CodePudding user response:

The current shell and the subshell that is spawned from the () syntax share the same stdout but are two different processes with different pids etc. This means that defining a variable a at the child process (subshell) doesn't affect the value of the variable a as defined at the parent process. In other words variable is not a shared resource between the two different processes. The following example describes this behavior:

Example

# script
echo "parent pid: $BASHPID";
a=255;
echo "(parent) a before: $a";
[[ a -eq 255 ]] && ( echo "subshell pid: $BASHPID"; \
                     echo "(subshell) a before: $a"; \
                     a=0; \
                     echo "(subshell) a after: $a"; \
                     b=255; )
echo "(parent) a after: $a"

# Output
parent pid: 839
(parent) a before: 255
subshell pid: 901
(subshell) a before: 255
(subshell) a after: 0
(parent) a after: 255
  • Related