(原创)Linux Shell程序空间、变量类型和export命令

时间:2022-05-29 23:17:26

【引言】本文是我的第一篇Linux博客,文章尝试以最简洁清晰的文字、图解和案例,把Linux Shell程序的2种变量类型介绍清楚,同时也将相关的概念如系统变量、set、env、sh、source、x可执行程序等也一并讲清楚。希望大家只要读这一篇文章,就掌握好有关Linux Shell 变量的本质和应用。

一、2种变量设置方式的比较

Shell 变量的设置方式存在2种形式。

1、本地变量(局部变量)

设置方式为 var1=value1

2、环境变量(全局变量)

设置方式为 export var2=value2

二者有什么差别呢?差别在于二者的运行空间不同。Linux Shell实际上是一个独立的程序,有着自己独立的程序内存空间,变量就存放在自身的内存空间中。当我们在Shell中再次调用sh 执行一段程序时,实际上启动了另一个Shell,自然另有一份内存空间。第1Shell称为父程序,第2Shell称为子程序。

 (原创)Linux Shell程序空间、变量类型和export命令


在这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 的环境变量能够被子程序继承,而本地变量则无法继承,不论是子程序的本地变量还是环境变量,都不会传递到父程序中。

 

三、系统变量

无论是本地变量还是环境变量,都是存放在内存之中,只要用户通过exitlogout退出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的环境变量则可以传给子程序。

 

总结:配置文件的作用是保存初始设置或程序运行状态,使之在系统重启后仍能重新使用或恢复状态。在配置文件中,以本地变量方式设置的仍然是本地变量,以环境变量设置的,仍然是环境变量。

 

四、3种执行方式的比较:shsourcex可执行程序

【案例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

#

从上面的案例操作结果可以看出:

1sh ep0执行时启动shell子程序,是在shell子程序空间执行脚本,所以不能访问到shell父程序中的本地变量。

2source ep0执行时,直接在当前shell程序空间执行脚本,所以可以访问当前shell程序中的本地变量。

3)直接执行脚本ep0,出人意料地也暗含启动了shell子程序,在子程序空间执行脚本。

所以,要想在当前shell程序空间执行脚本,必须用source