This is the summary of what I gathered from research:
There are two types: env variables and shell variables.
An environment variable is available, in a program and its child programs/processes/subshells. A shell variable is only available in the current shell.
https://askubuntu.com/a/26322/326584
First how echo $VAR
works
Whenever terminal/shell/bash sees $ symbol, it does something called "parameter expansion". Which means variables are replaced with values.
https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html
So if VAR
had value 'hello' then echo $VAR
becomes echo 'hello'
.
which means this works...
TEST=123
echo $TEST
// 123
but the following doesn't work because variable got replaced BEFORE the command was able to set the variable.
TEST2=999 echo $TEST2
// nothing...
but if you add the semicolon..
TEST2=999; echo $TEST2
it is same as..
TEST2=999
echo $TEST2
.. which works same as before.
And since shell variables are not passed to subprocesses/child, when you call a command it creates a new process, so...
TEST3=111
node -e 'console.log(process.env.TEST3)'
or
TEST3=111
printenv TEST3
both print nothing. Shell variables are not inherited by chld processes. Use export to make shell variable, an enviornment variable..
export TEST3=111
printenv TEST3
//111
There is one exception...
VAR=123 printenv VAR
VAR=123 VAR2=456 printenv VAR2 //even multiple vars
Basically if written it like this and right after call the command then it only temporarily sets environment var for that command. It doesn't even set shell var. Think of it as completely new syntax.
VAR=123 printenv VAR // 123
echo $VAR // nothing
VAR=123
echo $VAR // 123