HELLO=world echo $HELLO
In the above, bash
does parameter expansion before the statement is executed. That means that $HELLO
is replaced with nothing (or whatever the current value of HELLO is) before the statement is executed (which would include setting HELLO to world
).
Observe:
$ HELLO=world bash -c 'echo $HELLO'
world
Notice that echo $HELLO
is inside single quotes. Single quotes prevent parameter expansion. That means that HELLO is not evaluated until the bash
subshell starts up and sees it as an argument. By that time, HELLO will have been set equal to world
.
By contrast, consider this line in which the single quotes have been replaced with double quotes:
$ HELLO=world bash -c "echo $HELLO"
Here nothing prints because double-quotes do not suppress parameter expansion. Thus, the bash
command is given two arguments -c
and echo
. Hence, nothing prints.
All the gory details
man bash
explains, in detail, what happens when commands such as the above are processed:
When a simple command is executed, the shell performs the
following expansions, assignments, and redirections, from
left to right.
1. The words that the parser has marked as variable
assignments (those preceding the command name) and
redirections are saved for later processing.
2. The words that are not variable assignments or redi‐
rections are expanded. If any words remain after
expansion, the first word is taken to be the name of
the command and the remaining words are the arguments.
3. Redirections are performed as described above under
REDIRECTION.
4. The text after the = in each variable assignment
undergoes tilde expansion, parameter expansion, com‐
mand substitution, arithmetic expansion, and quote
removal before being assigned to the variable.
Consider again the command:
HELLO=world echo $HELLO
The argument to echo
undergoes parameter expansion in step 2 while bash
does not even begin to assign the new value to HELLO until step 4.
Best Answer
I'm guessing that if you run
you will not get Bash as return value, but Dash. You have the correct preamble, but that only matters if you run the script as
./test2.sh
after making it executable.Right now you force-run the script via the
sh
interpreter, which probably is Dash, and the[[]]
construct is a Bash specific one.That's "why?". If you just replace the double brackets with single ones (and change
#!/bin/bash
to#!/bin/sh
, since your script is now only using POSIX functions anyway) it should run as intended.Demonstration on Debian, with
test.sh
with contents:this happens: