I am reading a Linux shell scripting book and have found the following warning:

"Command substitution creates what's called a subshell to run the enclosed command. A subshell is separate child shell generated from the shell that's running the script. Because of that, any variables you create in the script aren't available to the subshell command".

I have tried to create a variable in my current bash shell's CLI and then enter the subshell to check whether I can print it on the screen. So yes, I can't do it, seems to be according the citation above. However, I have run the following script with command substitution:

ans=$(echo $var)
echo $ans

And the result is:


As I understood, it shouldn't print the value of var since the subshell shouldn't be able to "see it". Why does it happen?

  • But the comment in the book says it does. I even included $BASH_SUBSHELL variable to print out in the command substitution and it printed 1 which means it created a subshell.
    – Donatas
    Commented Sep 12, 2016 at 7:54
  • 4
    Your book isn't very good. Commented Sep 12, 2016 at 8:32
  • 1
    At the very least that statement is unclear and misleading, and otherwise it's just outright wrong, as you've demonstrated in this question. Commented Sep 12, 2016 at 8:40
  • 1
    Charitably I'd have to guess that the book means "are not available for assignment" (with the thinking that that means the "variable" is unavailable), but it's a very unhelpful way of saying so if that's really what they meant. Commented Sep 12, 2016 at 8:41
  • 1
    Read some of our questions on sushell, such as unix.stackexchange.com/questions/157957/… and unix.stackexchange.com/questions/138463/… Commented Sep 12, 2016 at 8:41

2 Answers 2


The statement:

Because of that, any variables you create in the script aren't available to the subshell command.

is false. The scope of a variable defined in the parent shell is the entire script (including subshells created with command substitution).


ans1=$(echo $var)
ans2=$(var=6; echo $var)
echo $ans1
echo $ans2

will give the result:


$var is resolved by the subshell:

  • if no local variable is specified, the value of three global variable is used
  • if a local variable is specified, it uses its value

See also the example 21-2.


The statement as quoted is not true. It is also not true that the variable has been pre-substituted before the subshell runs.

You can validate this directly using variable indirection:

$ x=hello
$ echo Result is $(y=x ; echo ${!y} ; echo world)
Result is hello world

The variable x is definitely available directly to the subshell (rather than having had its value previously expanded) because ${!y} reads from the variable whose name is stored in y - which didn't exist at the time the subshell was created.

A charitable reading of the passage from the book would be that it means to say that the "variable" is unavailable because you can't modify its value persistently. Any variable assignments you make within a subshell are not available to the parent shell afterwards, whether that's making new variables (like y) or assigning replacement values to existing variables. If the subshell assigned to x, the new value would have effect inside the subshell, but reading from it afterwards would give the original value:

$ x=world
$ echo $(x=hello ; echo $x)
$ echo $x

It's not a very clear way of expressing that, at least in the passage you've quoted. If the whole book is like that, you may be able to find a better one (or read questions here instead).

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .