shell 环境变量的作用域

概述:shell变量的作用域,就是shell变量的有效范围,在不同的作用域中,同名的变量不会相互干涉,就比如:A班级中有个叫小明的同学,B班级中也有一个叫小明的同学,由于他们不在同一个班级中,所以当在班级中叫到小明的名字的时候,不会造成混乱。

shell变量的作用域分为3种:

  • 局部变量(local variable):只能在函数内部使用,需要使用local命令(局部变量只能在函数内部使用,但在函数内使用的变量不全是局部变量)
  • 全局变量(global varlable):在当前的shell 进程中使用的变量,叫做全局变量
  • 环境变量(environment variable):可以在子进程中使用。

1. shell 局部变量

在shell函数中定义的变量默认也为全局变量,需要使用local命令来声明局部变量,观查下面两段代码演示说明:

[root@docker /variable]# vim function_1.sh
#!/bin/bash
#定义函数
function fun(){

        a=100
}
#调用函数
fun
#输出函数内的变量值
echo    $a
"function.sh" 12L, 69C 已写入
[root@docker /variable]# sh function_1.sh
100

看输出结果,变量a是在函数内部定义,但是在函数外部也可以得到变量a的值,证明它是一个全局变量。

[root@docker /variable]# vim function_2.sh
#!/bin/bash
#定义函数
function fun(){

   local a=50
}
fun
echo    $a
"function_2.sh" 12L, 77C 已写入
[root@docker /variable]# sh function_2.sh

[root@docker /variable]#

输出结果为空,说明变量a在函数外部无效,是一个局部变量,仔细看上面的脚本,使用local用来声明局部变量。


2. shell 全局变量

所谓全局变量,就是指变量在当前shell进程中都有效,每个shell进程都有自己的作用域,彼此之间互不影响,在shell脚本中定义的变量,默认就是全局变量.

打开2个shell窗口,在其中一个窗口定义一个变量a并赋值100,然后打印a的值,发现输出100;在另一个shell窗口同样打印a的值,发现输出结构为空。这说明全局变量a仅仅在定义它的shell进程中有效,对新的shell进程无效。如图所示

shell全局变量说明.png

**需要强调的是,全局变量的作用范围是当前的进程,打开一个 Shell 窗口就创建了一个 Shell 进程,每个 Shell 进程都是独立的,拥有不同的进程 ID,执行shell脚本时也会生成一个进程,也会有用一个进程ID,所以想要使全局变量在这些脚本文件中都有效需要使用source 命令或. ./a.sh 的方法(source a.sh 命令表示在当前进程执行shell脚本,和使用. ./a.sh 、. a.sh 效果相同) 演示如下: **

[root@docker /variable]# a=100
[root@docker /variable]# cat a.sh
#!/bin/bash
echo $a
b=200
[root@docker /variable]# cat b.sh
#!/bin/bash
echo $b
[root@docker /variable]# source a.sh
100
[root@docker /variable]# source b.sh
200
[root@docker /variable]#

3. shell 环境变量

全局变量旨在当前的shll进程中有效,对其他的进程和子进程都无效,如果使用==export==命令将全局变量导出,那么他就在所有子进程中都有效了,这称之为“环境变量”。

环境变量被创建时所处的进程称为父进程,如果在父进程中在创建一个细腻的进程来执行shell命令,那么这个新的进程被称作shell子进程,当shell子进程产生式,它会继承父进程的环境变量为自己所用,所以说环境变量可从父进程传给子进程,不难理解,环境变量还可以传递给孙进程。

创建shell子进程最简单的方式就是运行bash命令(如图所示)


进入shell的子进程.png
[root@docker ~]$ a=22       #定义一个全局变量
[root@docker ~]$ echo $a    #在当前Shell中输出a,成功
22
[root@docker ~]$ bash       #进入Shell子进程
[root@docker ~]$ echo $a    #在子进程中输出a,失败

[root@docker ~]$ exit       #退出Shell子进程,返回上一级Shell
exit
[root@docker ~]$ export a   #将a导出为环境变量
[root@docker ~]$ bash       #重新进入Shell子进程
[root@docker ~]$ echo $a    #在子进程中再次输出a,成功
22
[root@docker ~]$ exit       #退出Shell子进程
exit
[root@docker ~]$ exit       #退出父进程,结束整个Shell会话

可以发现,默认情况下,a 在 Shell 子进程中是无效的;使用 export 将 a 导出为环境变量后,在子进程中就可以使用了。

我们一直强调的是环境变量在 Shell 子进程中有效,并没有说它在所有的 Shell 进程中都有效;如果你通过终端创建了一个新的 Shell 窗口,那它就不是当前 Shell 的子进程,环境变量对这个新的 Shell 进程仍然是无效的。

环境变量也是临时的

通过 export 导出的环境变量只对当前 Shell 进程以及所有的子进程有效,如果最顶层的父进程被关闭了,那么环境变量也就随之消失了,其它的进程也就无法使用了,所以说环境变量也是临时的。


4. shell 配置文件(脚本)加载

无论是否是交互式、是否是登录式,Bash shell 在启动时总要配置其运行环境,例如初始化环境变量、设置命令提示符、指定系统命令路径等。这过程都是通过加载一系列的配置文件完成的,这些配置文件其实就是脚本文件。

Bash 官方文档说:如果是登录式的 Shell,首先会读取和执行 /etc/profile,这是所有用户的全局配置文件,接着会到用户主目录中寻找 /.bash_profile、/.bash_login 或者 ~/.profile,它们都是用户个人的配置文件。

Bash shell 有关的配置文件主要有 /etc/profile、/.bash_profile、/.bash_login、/.profile、/.bashrc、/etc/bashrc、/etc/profile.d/*.sh,不同的启动方式会加载不同的配置文件。

全局配置

/etc/profile此文件为系统的每个用户设置环境信息,当用户第一次登录时,该文件被执行。并从 /etc/profile.d 目录的配置文件中收集 shell 的设置。如果你有对 /etc/profile 有修改的话必须得 source 一下你的修改才会生效,此修改对每个用户都生效。

/etc/bashrc为每一个运行 bash shell 的用户执行此文件。当 bash shell 被打开时,该文件被读取。如果你想对所有的使用 bash 的用户修改某个配置并在以后打开的 bash 都生效的话可以修改这个文件,修改这个文件不用重启,重新打开一个 bash 即可生效。

用户配置

~/.bash_profile每个用户都可使用该文件输入专用于自己使用的 shell 信息,当用户登录时,该文件仅仅执行一次!默认情况下,它设置一些环境变量,执行用户的~/ .bashrc 文件。 此文件类似于 /etc/profile,也是需要需要 source 才会生效,/etc/profile 对所有用户生效,~/.bash_profile 只对当前用户生效。

~/.profile(由Bourne Shell和Korn Shell使用)和.login(由C Shell使用)两个文件是.bash_profile的同义词,==目的是为了兼容其它Shell==。

如下.bash_profile系统默认配置:

[root@docker ~]# cat ~/.bash_profile
# .bash_profile

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
    . ~/.bashrc
fi
# User specific environment and startup programs
PATH=$PATH:$HOME/bin
export PATH
[root@docker ~]#

~/.bashrc该文件包含专用于你的 bash shell 的 bash 信息,当登录时以及每次打开新的 shell 时,该文件被读取。(每个用户都有一个 ~/.bashrc 文件,在用户目录下) 此文件类似于 /etc/bashrc,不需要重启就可以生效,重新打开一个 bash 即可生效,/etc/bashrc 对所有用户新打开的 bash 都生效,但 ~/.bashrc 只对当前用户新打开的 bash 生效。
~/.bashrc文件会在bash shell调用另一个bash shell时读取,也就是在shell中再键入bash命令启动一个新shell时就会去读该文件。这样可有效分离登录和子shell所需的环境。但一般 来说都会在/.bash_profile里调用/.bashrc脚本以便统一配置用户环境。


5. 登录式shell和非登录式shell区别

  • 登录式shell

交互式登录:(清除掉所有变量,通过文件重新读入)

1.直接通过终端输入账号密码登录

2.使用“su - username”切换的用户

执行顺序:(影响该shell的配置文件)/etc/profile --> /etc/profile.d/.sh --> ~/.bash_profile–> ~/.bashrc–> /etc/bashrc

  • 非登录式shell

如果以非登录的方式启动 Shell,那么就不会读取以上所说的配置文件,而是直接读取 ~/.bashrc;~/.bashrc 文件还会嵌套加载 /etc/bashrc

1.su username

2.图形界面下打开的终端

3.执行脚本 (当我们执行脚本的时候.我们就已经进入到了一个子shell)

4.任何其它的bash实例
执行顺序:(影响该shell的配置文件)~/.bashrc–> /etc/bashrc–> /etc/profile.d/.sh

6.检查系统环境变量的命令

  • set 输出所有变量,包括全局变量、局部变量
  • env 只显示痊愈变量
  • declare 输出所有的变量,如同 set
  • export 只显示和设置环境变量值

7.删除环境变量

  • unset 变量名 ,删除变量或函数。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
禁止转载,如需转载请通过简信或评论联系作者。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,378评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,356评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,702评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,259评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,263评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,036评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,349评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,979评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,469评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,938评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,059评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,703评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,257评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,262评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,485评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,501评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,792评论 2 345

推荐阅读更多精彩内容

  • 关于Shell 为了能对shell能够有整体的认识,我们需要先简单介绍下Linux系统 。 Linux系统 Lin...
    QiShare阅读 2,268评论 0 2
  • bash shell中使用环境变量在内存中存储有关shell会话和工作环境的数据。以便程序或shell中运行的脚本...
    沐灵洛阅读 1,190评论 0 2
  • 一、变量的类型 变量可分为两类: 环境变量(全局变量) 局部变量 环境变量又被称为全局变量,可以在创建的shell...
    爱编程的iveBoy阅读 698评论 0 0
  • 全局环境变量全局环境变量对于shell会话和所有生成的子shell都是可见的。 局部变量则只对创建它们的shell...
    Captain_tu阅读 8,524评论 0 3
  • 环境变量 查看环境变量命令 设置全局环境变量 在设置全局环境变量的进程所创建的子进程中,该变量都是可见的。创建全局...
    黑球君阅读 755评论 0 0