I actually did not know there are two different types of variables I can access from the command line. All I knew is, that I can declare variables like:
foo="my dear friends"
bar[0]="one"
bar[1]="two"
bar[2]="three"
or accessing them with a $ sign, like:
echo $foo
echo ${bar[1]}
or using inbuilt variables, like:
echo $PWD
PATH=$PATH:"/usr/bin/myProg"
Now, I hear there are two (at least?) types of variables: shell variables and environment variables.
- What is the purpose of having two different types?
- How do I know which type a variable is?
- What are the typical usages for each one?
Best Answer
Environment variables are a list of
name=value
pairs that exist whatever the program is (shell, application, daemon…). They are typically inherited by children processes (created by afork
/exec
sequence): children processes get their own copy of the parent variables.Shell variables do exist only in the context of a shell. They are only inherited in subshells (i.e. when the shell is forked without an
exec
operation). Depending on the shell features, variables might not only be simple strings like environment ones but also arrays, compound, typed variables like integer or floating point, etc.When a shell starts, all the environment variables it inherits from its parent become also shell variables (unless they are invalid as shell variables and other corner cases like
IFS
which is reset by some shells) but these inherited variables are tagged as exported1. That means they will stay available for children processes with the potentially updated value set by the shell. That is also the case with variables created under the shell and tagged as exported with theexport
keyword.Array and other complex type variables cannot be exported unless their name and value can be converted to the
name=value
pattern, or when a shell specific mechanism is in place (e.g.:bash
exports functions in the environment and some exotic, non POSIX shells likerc
andes
can export arrays).So the main difference between environment variables and shell variables is their scope: environment variables are global while non exported shell variables are local to the script.
Note also that modern shells (at least
ksh
andbash
) support a third shell variables scope. Variables created in functions with thetypeset
keyword are local to that function (The way the function is declared enables/disables this feature underksh
, and persistence behavior is different betweenbash
andksh
). See https://unix.stackexchange.com/a/28349/25941This applies to modern shells like
ksh
,dash
,bash
and similar. The legacy Bourne shell and non Bourne syntax shells likecsh
have different behaviors.