Issue
S=2
echo $S
echo "$S"
bash -c " echo $S "
bash -c " echo '$S' "
bash -c " echo "$S" "
Why do all of these echo the same thing? They all print 2
and I don't understand why.
The most confusing one for me is bash -c " echo '$S' "
, since echo '$S'
= $S
. How come bash -c " echo '$S' "
works like the others?
Solution
bash -c " echo '$S' "
Because the string " echo '$S' "
is double quoted it is being interpolated by the outer shell. The single quotes aren't relevant at this stage. The outer shell expands $S
and the resulting command is:
bash -c " echo '2' "
Then the inner bash
command runs and, as you can see, the string being echoed is the fixed string '2'
with no variable.
bash -c " echo "$S" "
This looks like it contains quotes inside of quotes, but looks can be deceiving. What you actually have is " echo "
adjacent to $S
adjacent to " "
.
The result is still 2
, but I just wanted to point out that this isn't analogous to the bash -c " echo '$S' "
case above, which does have nested quotes.
Follow up case
bash -c ' echo "$S" '
You didn't write this form where the outer quotes are single quotes. If you had, you might be puzzled that it doesn't print 2
like the rest. That's weird. Why not?
Answer: Unlike all the versions you posted, this one has the inner shell doing the expansion of $S
. The command is single quoted which prevents the outer shell from expanding it, so $S
makes it intact to the inner shell. The inner shell, though, doesn't have a variable called $S
, and ends up just printing a blank line.
Why doesn't it have S=2
? It's because S
was not exported. In order for a variable to be visible in a child process it needs to be exported with
export S=2
or
S=2
export S
Unexported variables are only visible in the current process and are unset in child processes.
Answered By - John Kugelman Answer Checked By - David Goodson (WPSolving Volunteer)