On Wed, Feb 27, 2008 at 11:46:13AM -0600, Les Mikesell alleged:
Stephen Harris wrote:
Yes, but I'm looking for what happens before and after. Why does unset foo foo=bar >$foo do something you might expect, but unset foo foo=bar echo $foo >$foo doesn't?
What would you expect the last to do? "foo=bar echo $foo" only sets "foo" inside the scope of the "echo" statement, so in the scope of ">$foo" the variable is unset. In the first case there's no command so the shell is evaluating left-to-right and it works.
How does the shell know that there's no command without evaluating, and if it evaluates left to right, why isn't the result the same? Actually I found the answer to that, which is that name=val command is processed like (name=val; command) which also explains why the value isn't left lingering for the next operation.
If was like '(name=val; command)' then 'foo=bar echo $foo' would do what you want.
'name=val' is very different from 'name=val command'. They aren't parsed the same way and follow different rules. The first is a variable assignment. The second is a command execution with a supplied env list.
'name=val command' is not "evaluated from left-to-right". After all variable substitution, expansions, and word splitting is done, then the command is executed with the supplied env var.
'name=val >$name' is a weird case that I can't explain. It is not related to 'name=val command' because there is no command. It acts like two statements when syntacticaly it is one. It think it is a bug. Avoid it.