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