【引言】本文是我的第一篇Linux博客,文章尝试以最简洁清晰的文字、图解和案例,把Linux Shell程序的2种变量类型介绍清楚,同时也将相关的概念如系统变量、set、env、sh、source、x可执行程序等也一并讲清楚。希望大家只要读这一篇文章,就掌握好有关Linux Shell 变量的本质和应用。
Shell 变量的设置方式存在2种形式。
1、本地变量(局部变量)
设置方式为 var1=value1
2、环境变量(全局变量)
设置方式为 export var2=value2
二者有什么差别呢?差别在于二者的运行空间不同。Linux Shell实际上是一个独立的程序,有着自己独立的程序内存空间,变量就存放在自身的内存空间中。当我们在Shell中再次调用sh 执行一段程序时,实际上启动了另一个Shell,自然另有一份内存空间。第1个Shell称为父程序,第2个Shell称为子程序。
在这2个程序运行时,第1种变量设置方式var1=value1 设置的变量都存在自己的内存空间中,互相不能访问,因此称为本地变量。第2种变量设置方式export var2=value2的变量存放在一个特定的环境变量区,当在父程序Shell启动子程序Shell时,子程序会从这个特定的环境变量区继承父程序的环境变量,从而可以访问这些环境变量,但父程序不能访问子程序的环境变量。所以说,export的作用就是让子程序能够访问父程序的这些变量。
下面我们举例说明。
【案例1】
1、编写脚本ep0
#!/bin/bash
#ep0
echo "var0=$var0"
echo "evar0=$evar0"
echo "file_var0=$file_var0"
echo "FILE_EVAR0=$FILE_EVAR0"
2、按如下方式执行
# var0=value0
# export evar0=evalue0
# sh ep0
var0=
evar0=evalue0
file_var0=
FILE_EVAR0=
3、解释
var0是局部变量,evar0是环境变量。sh ep0 在父shell程序中,启动了子shell程序,继承父程序的环境变量,但不能访问父程序的局部变量,所以sh ep0时,var0为空值,evar0 为父shell程序设置的值evalue0。
【案例2】
1、编写以下脚本
#脚本ep1
myvar1="value 1"
mylv1="local value 1"
export myvar1
echo "ep1"
echo "ep1 myvar0 $myvar0"
echo "ep1 myvar1 $myvar1"
echo "ep1 mylv0 $mylv0"
echo "ep1 mylv1 $mylv1"
sh ep2
echo "ep1 myvar2 $myvar2"
echo "ep1 myvar3 $myvar3"
echo "exit ep1"
# 脚本ep2
myvar2="value 2"
mylv2="local value 2"
export myvar2
echo "ep2"
echo "ep2 myvar0 $myvar0"
echo "ep2 myvar1 $myvar1"
echo "ep2 myvar2 $myvar2"
echo "ep2 mylv0 $mylv0"
echo "ep2 mylv1 $mylv1"
echo "ep2 mylv2 $mylv2"
sh ep3
echo "ep2 myvar3 $myvar3"
echo "exit ep2"
#脚本 ep3
myvar3="value 3"
export myvar3
echo "ep3"
echo "ep3 myvar0 $myvar0"
echo "ep3 myvar1 $myvar1"
echo "ep3 myvar2 $myvar2"
echo "ep3 myvar3 $myvar3"
echo "ep2 mylv0 $mylv0"
echo "ep2 mylv1 $mylv1"
echo "ep2 mylv2 $mylv2"
echo "exit ep3"
2、按以下方式运行脚本
# mylv0="local value 0"
# export myvar0="value 0"
# sh ep1
ep1
ep1 myvar0 value 0
ep1 myvar1 value 1
ep1 mylv0
ep1 mylv1 local value 1
ep2
ep2 myvar0 value 0
ep2 myvar1 value 1
ep2 myvar2 value 2
ep2 mylv0
ep2 mylv1
ep2 mylv2 local value 2
ep3
ep3 myvar0 value 0
ep3 myvar1 value 1
ep3 myvar2 value 2
ep3 myvar3 value 3
ep3 mylv0
ep3 mylv1
ep3 mylv2
exit ep3
ep2 myvar3
exit ep2
ep1 myvar2
ep1 myvar3
exit ep1
# echo $mylv0
local value 0
# echo $mylv1
#
3、解释
程序的执行清晰地表明,父程序export 的环境变量能够被子程序继承,而本地变量则无法继承,不论是子程序的本地变量还是环境变量,都不会传递到父程序中。
三、系统变量
无论是本地变量还是环境变量,都是存放在内存之中,只要用户通过exit或logout退出Linux Shell程序,那么这些变量设置都会消失,再次login 进入Shell程序或调用Shell程序,所有变量都不会存在。
一些系统或程序的初始设置或运行状态,需要在下次login进入Shell程序时再次使用,所以必须永久保存。系统将这些设置存放在配置文件中,每次login进入Shell程序时,都自动读取这些数据对系统进行初始化,以达到复现初始设置或运行状态。这些根据配置文件设置的变量,我们暂且称之为系统变量。
系统配置文件有全局配置文件/etc/profile ,Shell环境配置文件如/etc/bashrc,用户环境变量~/.bash_profile、~/.bashrc等。
在配置文件中,变量设置同样有2种方式,即本地变量和环境变量。
【案例3】
1. 在root 的Home目录中,编辑.bash_profile,增加以下几项。
#test
file_var0="file value 0"
export FILE_EVAR0="file environment value 0"
2. 退出系统,重新登录
3. 查看环境
# env
从输出的内容中可以找到
FILE_EVAR0=file environment value 0
但没有file_var0='file value 0' ,说明env是环境变量集。
# set
从输出的内容中可以找到
FILE_EVAR0='file environment value 0'
file_var0='file value 0'
说明set是变量全集。
4. 执行案例1中的ep0脚本
#sh ep0
var0=
evar0=
file_var0=
FILE_EVAR0=file environment value 0
执行结果说明,不论是不是在配置文件中设置,本地变量都不能传给子程序,而export的环境变量则可以传给子程序。
总结:配置文件的作用是保存初始设置或程序运行状态,使之在系统重启后仍能重新使用或恢复状态。在配置文件中,以本地变量方式设置的仍然是本地变量,以环境变量设置的,仍然是环境变量。
【案例4】
续案例3操作后,按以下步骤执行操作
# var0="value 0"
# export evar0="export value 0"
# sh ep0
var0=
evar0=export value 0
file_var0=
FILE_EVAR0=file environment value 0
# source ep0
var0=value 0
evar0=export value 0
file_var0=file value 0
FILE_EVAR0=file environment value 0
# chmod a+x ep0
# ./ep0
var0=
evar0=export value 0
file_var0=
FILE_EVAR0=file environment value 0
#
从上面的案例操作结果可以看出:
(1)sh ep0执行时启动shell子程序,是在shell子程序空间执行脚本,所以不能访问到shell父程序中的本地变量。
(2)source ep0执行时,直接在当前shell程序空间执行脚本,所以可以访问当前shell程序中的本地变量。
(3)直接执行脚本ep0,出人意料地也暗含启动了shell子程序,在子程序空间执行脚本。
所以,要想在当前shell程序空间执行脚本,必须用source。