31

How can we prevent parameter expansion? Does the Bash's Manual mention this somewhere? I'd appreciate if you could help me to locate where it is mentioned there.

For example,

$ b=1
$ echo $b
1

When the bash interpreter interprets echo $b, the parameter expansion $b happens before running echo $b. So there is no need to make b a environment variable of the shell process, in order to be passed to the subprocess for echo $b.

For comparison, consider another example from https://unix.stackexchange.com/a/261406/674

$ b=1
$ c=$(b=2; echo $b)
$ echo $c
2

In the original shell, when the bash interpreter interprets c=$(b=2; echo $b), it doesn't expand $b using the value 1.

In the subshell of the command substitution, when the bash interpreter interprets b=2; echo $b, it expands $b using the value 2.

What prevents the parameter expansion $b in the original shell, and leaves the parameter expansion $b till the subshell?

Quotes can prevent parameter expansions, e.g. "$b". But here there are no quotes around the parameter expansion. Does command substitution prevent parameter expansion in it?

3
  • in the subshell, between ( and ) you have assigned b a value of 2 and echoed it out. The output from this subshell became the value of the variable c. The b=1 from the first line has no importance in the subshell. Is there a confusion here that I can not see ?
    – MelBurslan
    Feb 11, 2016 at 18:44
  • 1
    Why do you expect the echo $b to be echo 1 if it was assigned 2 just before the echo? Feb 11, 2016 at 18:46
  • @cuonglm: do you mean command substituion prevent parameter expansion in the original shell? Are there other similar cases?
    – Tim
    Feb 12, 2016 at 8:54

1 Answer 1

50

You have mistaken, double quotes "$b" does not prevent parameter expansion, it prevents pathname expansion (aka globbing) and fields splitting.

If you want to prevent parameter expansion, you need to use quoting, like single quote '$b' or escaping \$b:

$ echo '$b'

or:

$ echo \$b

then $b is output literally.


In the example, there's nothing to prevent parameter expansion.

When the shell read the input c=$(b=2; echo $b), it performs token recognition, saw that $( is the token for command substitution. So it treats the rest of string between $( and ) to be interpreted in the subshell created by command substitution, not the current shell.

3
  • 1
    Yeah; the bash is just an interpreter. It follows the rules it is programmed by, so there could be exceptions - like evaluating everything except for given context. This is common in all(or almost all) languages, nothing strange. It just makes sense. Also, bash isn't implemented in bash, so it's not like they had to use magic tricks to make this work. Feb 12, 2016 at 9:07
  • It is absolutely necessary to apply this method for escaping expansion when passing text to a file from a script. This worked properly for me when using "<<END_TEXT" on a string that contained variables within it.
    – suprematis
    Nov 6, 2020 at 20:42
  • 1
    @suprematis: actually that's not necessary; if you quote the delimiter-word or any part of it, like <<'END' or <<'E'ND or <<\END, then no expansions are done in the heredoc body. See gnu.org/software/bash/manual/html_node/… . Feb 20, 2022 at 1:41

You must log in to answer this question.

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