mmilleruva
mmilleruva

Reputation: 2178

How to set environment variables for a shell command

I often see this command in node.js programs: NODE_ENV=test node app.js which sets the NODE_ENV variable to test and works. I also read here https://en.wikipedia.org/wiki/Environment_variable that this should work for any shell command, but running some tests on my own, here is what I see

$ HELLO="WORLD"
$ HELLO="MARS" echo "$HELLO"
  WORLD
$

I would expect this to print MARS. Is there something I am missing here?

Upvotes: 3

Views: 138

Answers (2)

philippe lhardy
philippe lhardy

Reputation: 3286

Other answers are correct, but here a refinement :

There are 2 cases in fact when defining a list of variable separated by spaces in bash whether it ends or not with a command.

VAR1=value1 VAR2=value2 ... VARn=valuen command arg1 arg2 ... argn

and

VAR1=value1 VAR2=value2 ... VARn=valuen

don't export VAR1 ... VARn the same way.

In first case VAR1 ... VARn will be set only for command and will then not be exported to current shell.

In second case VAR1 ... VARn will alter current shell.

then ( remark that ';' is very same of using a new line )

HELLO=WORLD
HELLO=MARS echo "i don't export HELLO."
echo "HELLO=$HELLO"

will display

i don't export HELLO.
HELLO=WORLD

and

HELLO=WORLD
HELLO=MARS ; echo "i did export HELLO."
echo "HELLO=$HELLO"

will display

i did export HELLO.
HELLO=MARS

Upvotes: 0

RealSkeptic
RealSkeptic

Reputation: 34628

The syntax VAR=value command means that the command will be invoked with the environment variable VAR set to VALUE, and this will apply only for the scope of that command.

However, when you are using the command line:

HELLO="MARS" echo "$HELLO"

The shell first interprets the "$HELLO" parameter, determines that it is WORLD, and then what it actually does is run:

HELLO="MARS" echo "WORLD"

So the echo may have the HELLO variable set, but it doesn't affect what it prints - it has already been interpreted before.

Doing

HELLO="MARS"; echo "$HELLO"

does something else entirely. First it sets HELLO to MARS in the current shell, and then it goes on to interpret the echo command. By this time HELLO contains MARS, not WORLD. But this is an entirely different effect - the variable HELLO stays with the value MARS, which is not the case in the command without the ;.

Your problem is that echo is just a poor choice for a demonstartion of this. You can do other demonstrations to prove that HELLO is changed properly:

HELLO="MARS" eval 'echo $HELLO'

In this case, the shell will not interpret the $HELLO because it is within a string in single quotes. It will first put MARS in HELLO, and then call the eval 'echo $HELLO' with that variable set. The eval command with then run echo $HELLO, and you'll get the output you were expecting.

This syntax is best used for things that don't use the given variable as part of the command line, but rather use it internally.

Upvotes: 3

Related Questions