I think I'm having a massive brainfart. I would expect

env foo=bar echo $foo

...to print bar, but I get an empty line instead. Wat.

The same happens if I use the bash syntax:

foo=bar echo $foo

A similar question was answered recently: the symbols are evaluated in the line before the symbol is defined in this line, making it necessary to split the definition and use of the symbols to separate lines.

Prompted by a comment, you could have done this:

foo=bar bash -c 'echo $foo'

which first assigns a value to foo and passes that into a new process as an environment variable where it can be printed.

You can read more about it in POSIX Shell Command Language Token recognition.

Following up from @mikeserv comment:

  • POSIX is not explicit enough to give the whole answer.
  • At the beginning of the cited section, it says

    The shell shall read its input in terms of lines from a file, from a terminal in the case of an interactive shell, or from a string in the case of sh -c or system().

  • at the end, it says

    Once a token is delimited, it is categorized as required by the grammar in Shell Grammar.

  • but POSIX does not say explicitly that the entire line is tokenized before working on the grammar.
  • in that case, we rely on existing practice - the shell conforms because nothing contradicts the written standard, but the standard cannot be used to predict the behavior in all cases.
  • the same comment applies, of course, to the behavior of aliases (which is why I referred to it as a similar question).
  • or if you are okay with quoting hell, env foo=bar bash -c 'echo $foo' – badp Nov 9 '15 at 9:49
  • Actually, the alias question relies upon the token-recognition section's implication that tokens are all computed for a given line before moving on to the grammar. But for both, the standard is not explicit, making you rely on existing practice. – Thomas Dickey Nov 9 '15 at 10:12
  • @thomasdickey - yeah, that was my gist too. you know, when you're writing a comment if you do @username...comment the user you specify will get a little message letting them know you were talking to them. well, they will if its thread-relevant. – mikeserv Nov 9 '15 at 10:18
  • @mikeserv (like this). hmm - I'll keep that in mind (though how it works with embedded blanks was not apparent). – Thomas Dickey Nov 9 '15 at 10:25
  • like that. tangentially, i had a look at luit.c and i think i can just change setup_io(){ ... ;fnctl(0, [GS]ETFL, 0);...} to do 2 for the first argument. well, i guess the copyTermios() and setRawTermios() functions might need a little modification as well, but it should be simple, i think. the rc = (return) for every line seems strange - but i'm no C programmer either. is that your thing or was that inherited? and if your blanks comment is referring to "${set_null_var:=new val and $(echo other stuff)}" you're mostly safe w/ anything. some shells will do weird stuff with }. – mikeserv Nov 9 '15 at 10:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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