Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

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?

share|improve this question
add comment

4 Answers

up vote 6 down vote accepted

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.

share|improve this answer
1  
Also, note that since foo is set as a prefix to the echo command, it's only set for that command (and not for subsequent commands). Compare with foo=bar eval 'echo eval sees $foo'; echo echo sees $foo (here, since $foo is expanded within the eval command, the value will be substituted there, but not for the next echo command). –  Gordon Davisson Oct 25 '10 at 19:30
    
Thank you both. This is exactly what I wanted to know. –  cYrus Oct 25 '10 at 20:44
1  
This is an assignment in the child's environment (i.e. echo in the original question or eval in Gordon's example). Variable assignments in the child's environment do not affect variable values in the parent's. foo=bar eval 'foo=$foo'; echo $foo outputs only a newline. –  Dennis Williamson Oct 25 '10 at 20:55
    
From man bash: "If no command name results, the variable assignments affect the current shell environment. Otherwise, the variables are added to the environment of the executed command and do not affect the current shell environment. If any of the assignments attempts to assign a value to a readonly variable, an error occurs, and the command exits with a non-zero status." –  Dennis Williamson Oct 25 '10 at 21:02
add comment

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.

share|improve this answer
    
Thanks, but I know how to work around to the problem. I only was interested on the example I provided. –  cYrus Oct 25 '10 at 20:34
    
+1: Nice set of alternatives though. This might come handy to someone. –  cYrus Oct 25 '10 at 20:48
add comment

Try:

foo=bar; echo $foo
       ^

Mind the ; since you're trying to fit two seperate commands on a single line. They don't work together by default.

share|improve this answer
    
See my other comment. –  cYrus Oct 25 '10 at 20:35
add comment

A proper way to do it would be:

foo=bar sh -c 'echo $foo'
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.