This article talks about the variable scope
in shell, especially how to access variables between different scripts.
Local Variables
The set
command displays all functions and local variables defined for a specific process:
1 | # this definition will be in `set`, not in `env` |
It also sorts the display alphabetically.
注意set
中的variables 不一定出现在env
中,顾名思义, env
中显示的才是当前运行shell会被采用的variables.
ENV Variables
Environment variables are visible from the shell session and from any spawned child subshells, and also visable by the command launched from that shell. This makes environment variables useful in applications that create child subshells, which require parent shell information.
To view environment variables, use the env
or the printenv
command:
1 | env | grep ^HOME |
You can use export
to create environment variable.
1 | export demo='hello world' |
You can use unset
to remove an existing environment variable.
1 | unset demo |
If you want to only set the variable for one command in one use, just prefix it, eg:
1 | # EDITOR will only works for crontab command |
A common trick for programmers is to include the single dot
symbol in their PATH
environment variable. The single dot symbol represents the current directory:
1 | PATH=$PATH:. |
Declare Command
Note that declare
can print both set
and env
variables:
1 | declare | grep ^HOME= |
declare
command can be used to create local variables in set
or export to env
:
1 | # -i: integer |
You can mix the option:
1 | declare -x -l EDITOR |
Other ways to convert char to lower/upper case:
1 | val=abcdEFG |
Create constant (read-only) variable, cannot be unset and sustain for the shell session:
1 | ## set name as readonly |
Declare different kind of arrays, see my other blog Array in Script
:
1 | ## index-based |
Shell Variables
Shell variables (actually the local variable) are available only in the shell that creates them. In fact, the Linux system also defines standard shell environment variables for you by default.
How to define a Shell environment variable: No space can appear between the variable, the equal sign, and the value:
1 | var1=value |
Variables defined within the shell script maintain their values throughtout the life of the shell script but are vanished when the shell script completes.
If you want to assign the value of one variable to another, must use $
:
1 | var2=${var1} |
otherwise, var1
will be interpreted as text string.
1 | var2=var1 |
Variable Scope
My question is how to pass variables from one script to another? Basically there are 3 options:
-
Make the variable an environment variable (
export
it) before calling the child script (./script2
). -
source
the child script and it will run in the same shell, This would let you share more complex variables like arrays easily, but also means that the other script could modify variables in the caller shell. -
pass as parameters to child script:
./script2 var1 var2
-
if use
exec
to replace current process, still need export variable.
Preserve ENV variables
Refer to this question. This is interesting and easy to make mistake, if I want to preserve global ENV variable when switch user in shell, use su xxx
instead of su - xxx
, -
option will do:
- clears all environment variables except for TERM
- initializes the environment variables HOME, SHELL, USER, LOGNAME, PATH
- changes to the target user’s home directory
- sets argv[0] of the shell to ‘-’ in order to make the shell a login shell
But be very careful not let shell do variable expanding in command option:
1 | su xxx -c "... echo $a" |
Here $a
will be expanded before executing, use single quote or escape the $
sign:
1 | su xxx -c '... echo $a' |