1

The bash 4.1 manpage states (emphasis added)...

Simple Commands

A simple command is a sequence of optional variable assignments followed by blank-separated words and redirections, and terminated by a control operator. The first word specifies the command to be executed, and is passed as argument zero. The remaining words are passed as arguments to the invoked command.

Verifying the version on my system (NOT patched for shellshock)...

#  bash --version
GNU bash, version 4.1.0(1)-release (i686-pc-linux-gnu) ...

However, preceding variable assignments, without semicolons, are supposed to be a way to localize environment variable values for the life of that one command invocation only, but do not seem to ...

#  x=123 echo $x; unset x; echo $x
bash: x: unbound variable
#  x=123; echo $x; unset x; echo $x
123
bash: x: unbound variable
#  x=123; echo $x | tr '1' 'a'; unset x; echo $x
a23
bash: x: unbound variable
#  x=123 echo $x | tr '1' 'a'; unset x; echo $x
bash: x: unbound variable
bash: x: unbound variable
#  x="123" echo "$x" | tr '1' 'a'; unset x; echo $x
bash: x: unbound variable
bash: x: unbound variable
#  x="123"; echo "$x" | tr '1' 'a'; unset x; echo $x
a23
bash: x: unbound variable

Solution
Per this answer from another question it appears that the command must deliberately use the environment variables of its parent and echo does not. But shell invocations like bash -c do ...

x=123 bash -c 'echo $x'; unset x; echo $x
123
bash: x: unbound variable

Resources

DocSalvager
  • 2,152

1 Answers1

4

This line

x=123 echo $x

is evaluated in the following order:

  1. $x is expanded to the value of x in the current shell.
  2. The value of x in the environment of the command to be executed is set to 123
  3. The expanded command line is searched for a command, and echo is found.
  4. echo is run in an environment where x is set to 123, and $1 is set to whatever value x had in step 1.
  5. echo outputs $1 to standard output, but otherwise ignores the other values in its environment.

Note that $x as an argument is separate from the x that precedes the command.

ilkkachu
  • 138,973
chepner
  • 7,501