5

I've just come across this code snippet:

$ DEVELOPMENT=1 node dev-mode.js

This line runs node.js program and sets the environment variable DEVELOPMENT. I don't understand what the mechanism is used to set env variable? Is this the valid syntax:

$ [var1=value1 var2=value2] [process_name process_params] ?
Inian
  • 80,270
  • 14
  • 142
  • 161
Max Koretskyi
  • 101,079
  • 60
  • 333
  • 488
  • You want to know ways to set environment variables? – Inian Dec 16 '16 at 11:35
  • I want details about this specific way of setting environment variables – Max Koretskyi Dec 16 '16 at 11:36
  • @Maximus: Let me know if my answer below is what you intended to know. – Inian Dec 16 '16 at 11:48
  • @JamesBrown With `FOO=bar /bin/echo $FOO`, it's still the parent that retrieves the FOO variable. You want `FOO=bar sh -c '/bin/echo $FOO'` to have the child (in this case a shell as echo doesn't do that kind of thing) do it. – Petr Skocik Dec 16 '16 at 11:51
  • Here is some discussion on subject: http://stackoverflow.com/questions/7128542/how-to-set-an-environment-variable-only-for-the-duration-of-the-script – James Brown Dec 16 '16 at 11:53

3 Answers3

6

There are two ways to set the pass variables from your current shell a running program,

Either use the export built-in with syntax as

$ export MYVALUE=5
$ echo "MYVALUE is $MYVALUE"
MYVALUE is 5

This syntax allows the variable to take effect in current shell in all the subsequent sub-shells you are invoking( for command-substitution or process-substitution, etc) and the variable stays alive even after the sub-shells are terminated.

(or) as asked in the question, if you directly send it to the command as

$ MYVALUE=5 bash -c 'echo "MYVALUE is $MYVALUE"'
MYVALUE is 5

the value is passed only to the sub-shell(the one started with bash -c) and has no effect on parent shell once it exits. You can observe the MYVALUE from the above syntax now, it will be empty.

$ echo $MYVALUE
$

Hope this answers your question.

Inian
  • 80,270
  • 14
  • 142
  • 161
  • The first code example is misleading as the `"MYVALUE is $MYVALUE"` string is interpreted by the parent shell where `$MYVALUE` would get expanded even without the `export`. – Petr Skocik Dec 16 '16 at 12:50
2

This example should demonstrate:

X=0; Y=1;       #set X and Y
#set X, Y for the child and have it expand and print those vars
X=42 Y=43  sh -c 'echo $X $Y' 
#print the same vars in the parent
echo $X $Y      

The

var0=val0 var1=val1... command

syntax makes it act as if the variable list preceding the command was temporarily assigned the corresponding values and the variables were exported as with

export var0

After the command runs, the variables in the variable list have their original values and export status (=whether they automatically propagate to child processes) restored.

The example prints

42 43 
0 1
Petr Skocik
  • 58,047
  • 6
  • 95
  • 142
  • thanks, is my understanding correct that `$ X=0; Y=1;` without preceding `export` won't be available inside `$ sh -c 'echo $X $Y'`? – Max Koretskyi Dec 16 '16 at 12:16
  • Correct. In bash you can do `declare -p variable_name` to show the export flags and other properties of a variable. You can use it to explore the behavior of these mechanisms. As far as exports are concerned, dash and other shell behave the same, AFAIK, but I'm not sure if this behavior if POSIX mandated. – Petr Skocik Dec 16 '16 at 12:48
2

Yes, it's a valid syntax, it's described in Simple Commands section of the 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.

Arkadiusz Drabczyk
  • 11,227
  • 2
  • 25
  • 38