10
a=2
a=3 echo $a     #prints 2

can someone explain why would anyone use the above code in line-2. a=3 will be ignored as there is no "enter" after it. But I saw it in script like above and not sure about the purpose.

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
user5803214
  • 111
  • 5
  • 3
    `$a` is expanded before `a=3` is evaluated. Usually, `var=val command` is used to set an environment variable to be seen by `command` during its execution, but nowhere else. In this case `$a` will be `3` ‘within’ `echo`, but its argument is still `2`. – Biffen Jan 26 '16 at 16:28
  • It's probably because someone wanted to test your conclusion. – Maroun Jan 26 '16 at 16:28
  • @Biffen - Spot on. You should make that an answer. – Mr. Llama Jan 26 '16 at 16:30
  • @Biffen thx for explaining. – user5803214 Jan 26 '16 at 16:36
  • Even if it *did* work, I can't imagine a situation where you would want `a=$value echo $a` over `echo $value`. – chepner Jan 26 '16 at 17:37
  • The purpose, in the script you saw, was to set the variable **in the environment** for the duration of the command being run -- implying that that command, unlike `echo`, inspects and modifies its behavior based on environment variables. – Charles Duffy Jan 26 '16 at 17:45
  • @chepner -- it would be useful if `a` were a long string and one wanted to use it multiple times in the rest of the command line. For instance I came here because I want to do a `find . -type d` and egrep directories out of the output. They may appear /between/ slashes or at the end$ of a & I want to trim both with egrep. My regex-fu isn't strong enough to come up with a way to do both in the same egrep, but I can chain multiple egreps and get the effect I want. Since there are several directories I want to trim, my `a` would look something like this: a="foo|bar|baz" find . -type d | egrep ... – JohnnyLambada Dec 09 '22 at 17:12
  • 1
    @JohnnyLambada That's what *any* variable is for. You don't need special syntax to allow it. Pre-command assignments are for something different; altering the *environment* in which a command executes, not the command line to *produce* the command to execute. – chepner Dec 09 '22 at 17:35

2 Answers2

14

$a is expanded by the shell (Bash) before a=3 is evaluated. So echo sees its argument as 2, which is what it prints. (If you set -x you can see that what gets executed is a=3 echo 2.)

var=val command is used to set an environment variable to be seen by command during its execution, but nowhere else. So when command reads environment variables (e.g. using getenv()), to it $var is val.

If echo were to look up $a while running, it would have the value 3.

chepner
  • 497,756
  • 71
  • 530
  • 681
Biffen
  • 6,249
  • 6
  • 28
  • 36
7

The parent process expands a before the environment is setup in which it sets a different value (3) for a. Despite the fact that variable a set to 3 by the echo executes, the value was expanded already. So it's too late.

You can instead do:

a=3 bash -c 'echo $a'
P.P
  • 117,907
  • 20
  • 175
  • 238