Unexpected behavior in Bash

From man bash:

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.

So it's perfectly legal to write:

foo=bar echo $foo

but it doesn't work as I expect (it prints just a newline). It's quite strange to me since:

$ foo=bar printenv
foo=bar
TERM=rxvt-unicode
[...]

Could someone please explain me where I'm doing wrong?


This happens because variable expansion is done before the command is run. At the time variable expansion happens, foo is not set, so it expands to the empty string. The command then runs, setting foo.


If you are doing foo=bar and echo $foo on one line, it will not work. You will have to do one of three things.

  1. Run them as seperate commands. i.e: foo=bar Enter echo $foo

  2. Run them on one line, but with a semicolon between the two. ie: foo=bar; echo $foo

  3. Same as #2, but with double-ampersands. ie: foo=bar && echo $foo

The difference between 2 and 3 is that 3 will only execute echo $foo if foo=bar succeeded.