What's the difference between:
a=b
and
export a=b
In bash?
I understand that they both define environment variables, but I don't fully understand the difference.
What's the difference between:
a=b
and
export a=b
In bash?
I understand that they both define environment variables, but I don't fully understand the difference.
export propagates the variable to subprocesses.
For example, if you did
FOO=bar
then a subprocess that checked for FOO wouldn't find the variable whereas
export FOO=bar
would allow the subprocess to find it.
But if FOO has already been defined as an environment variable, then FOO=bar will modify the value of that environment variable.
For example:
FOO=one # Not an environment variable
export FOO # Now FOO is an environment variable
FOO=two # Update the environment variable, so sub processes will see $FOO = "two"
Older shells didn't support the export FOO=bar syntax; you had to write FOO=bar; export FOO.
If you don't use export, you're not defining an environment variable; just a shell variable.
Shell variables are only available to the shell process; environment variables are available to any subsequent process, not just shells.
Also, if you want to have the variable available to the calling shell without using export you can do this:
File a.ksh is -
#!/bin/ksh
FOO=bar
On the prompt, run this is
> . a.ksh
This will run the commands within the same shell and $FOO will be available.
Whereas,
> a.ksh
Will make $FOO available only within a.ksh, after the call to a.ksh it would not exist.
In addition to what has already been answered, both of these statement do not necessarily define (i.e. create vs set) an environment variable as "a" might already exist as a shell or environment variable.
In the latter case, both statements are strictly equivalent.
A script to demonstrate effect of export (let's call it export-demo.sh):
#!/bin/bash
Just function definition, no code executed here yet
function some_function() {
echo " function:var: $var"
#local var
var="Set in function"
echo " function:var: $var"
}
Define variable
var="Set in top script"
#export var
echo script:var: $var
This is sub-shell
(
echo " sub-shell:var: $var"
var="Set in sub-shell"
echo " sub-shell:var: $var"
)
echo script:var: $var
This sub-process (could be any executable actually)
bash -c '
echo " sub-process:var: $var"
var="Set in sub-process"
echo " sub-process:var: $var"
'
This script function call
echo script:var: $var
some_function
echo script:var: $var
Executed without export (it's commented out) produce this output:
$ bash export-demo.sh; echo shell: $var
script: Set in top script
sub-shell: Set in top script
sub-shell: Set in sub-shell
script: Set in top script
sub-process:
sub-process: Set in sub-process
script: Set in top script
function: Set in top script
function: Set in function
script: Set in function
shell:
As we can see, script-level defined variable:
local, see below);Let's un-comment export var line and run the script again:
$ bash export-demo.sh; echo shell: $var
script:var: Set in top script
sub-shell:var: Set in top script
sub-shell:var: Set in sub-shell
script:var: Set in top script
sub-process:var: Set in top script
sub-process:var: Set in sub-process
script:var: Set in top script
function:var: Set in top script
function:var: Set in function
script:var: Set in function
shell:
That's exactly what export does: it exports shell variable as process environment variable for sub-processes, which the script may spawn. No changes from sub-process propagated to upper script (because it's also gets copy of original variable).
Please, note, no changes to upper shell done (last output line). It's because script run from shell as sub-process, even if called as:
$ chmod +x export-demo.sh; ./export-demo.sh
(An only way to get rid of sub-processing script on run is to source it to current shell session as noted in this answer.)
Bonus. Let's un-comment local var line and run the script again:
$ bash export-demo.sh; echo shell: $var
script:var: Set in top script
sub-shell:var: Set in top script
sub-shell:var: Set in sub-shell
script:var: Set in top script
sub-process:var: Set in top script
sub-process:var: Set in sub-process
script:var: Set in top script
function:var: Set in top script
function:var: Set in function
script:var: Set in top script
shell:
As we can see, variable defined as local in function gets copy of upper script and can't change upper script variable value.