linux 环境变量及其配置方式

本文详细探讨了shell、环境变量及其配置文件bash在Linux系统中的工作原理。讲解了环境变量与普通变量的区别,以及login shell与non-login shell的差异。通过两个范例解析了环境变量的形成过程,并解答了关于不同配置文件对环境变量影响的常见问题。总结强调了理解shell进程集合和正确修改环境变量的重要性。


一、shell

狭义的shell是bash(或sh或…)这个进程;广义的shell是bash(或sh或…)这个进程 以及 bash的父进程的集合!下文提到的shell广义的,并且bash或sh等都用bash指代!

bash在检查输入指令时,判断是内置的还是外部的file。如果是内置的,bash将在自己的内存空间根据输入数据继续执行;如果是外部的file,bash会创建子进程,并替换为输入命令的程序,这个子进程继承了bash的环境变量!

二、环境变量

环境变量可以理解为存储在bash进程内存空间的特殊内存块的变量。环境变量与普通变量的区别是,环境变量可以被bash的子进程继承,而普通变量不行。看如下范例:

root@study:~# name=haha			# 设置普通变量
root@study:~# echo ${name}		# 打印成功
haha
root@study:~# bash				# 切换bash,为上一个bash的子进程
root@study:~# echo ${name}		# 打印为空,说明这个子bash没有继承到普通变量

root@study:~# exit				# 回到原来的bash
exit
root@study:~# export name		# export刚刚定义的变量,使其成为环境变量
root@study:~# bash				# 再次创建并进入子bash
root@study:~# echo ${name}		# 打印成功,说明这个子bash继承了环境变量
haha

三、bash环境配置文件

bash的环境变量不是凭空产生的。在计算机运行过程中,shell根据某些磁盘文件初始化环境变量并最终保存在bash内存空间里。

在展开问题之前,我们先了解两个概念,分别是 login shell 与 non-login shell。废话不多说,直接上图吧!
non-login shell
图一 non-login shell

login shell
图二 login shell

区分的依据是用户登录login shell需要输入账号密码,而登录non-login shell则不需要!一般来说,图形界面的terminal就是non-login shell,而字符界面就是login shell。

为便于下文描述,我们简单描述下 shell 集合的进程树结构

# login shell进程树:
A_proc───B_proc───bash
# 这个模型对应图二输入账号密码登录后的情形

# non-login shell进程树:
C_proc───D_proc───bash
		        └─bash
			    └─bash
# 这个模型对应图一打开多个终端的情形
			    
# 此外,较为特殊的non-login shell进程树,可能长这样:
A_proc───B_proc───bash───bash	# 以最后一个bash作结尾的进程集合是non-login shell

接下来,具体看两个范例!

范例一:从计算机启动到登录login shell的过程,说明环境变量的形成过程。
步骤如下:
1.计算机启动,进入图二状态,等待输入账号密码。此时系统只有进程A_proc,还没有创建B_proc。A_proc读取系统配置文件 /etc/profile,初步形成bash所需的环境变量;
2.输入账号密码成功后,A_proc创建B_proc。B_proc作为进程A_proc的子进程,继承步骤1的环境变量。同时,B_proc会读取自己账户的配置文件 ~/.bash_profile(或~/.bash_logout或~/.profile),形成自己用户的所有可用的环境变量。
3.B_proc主动创建bash进程。bash进程继承了B_proc的环境变量。至此,该bash就具有了 /etc/profile~/.bash_profile 设置的变量了!

范例二:从计算机启动到登录non-login shell的过程,说明环境变量的形成过程。
步骤如下:
1.计算机启动,进入图形界面,等待输入账号密码。此时系统只有进程C_proc,还没有D_proc。C_proc读取系统配置文件 /etc/profile,初步形成bash所需的环境变量;
2.输入账号密码成功后,C_proc创建D_proc,D_proc作为进程C_proc的子进程,继承步骤1的环境变量。同时,D_proc会读取自己账户的配置文件 ~/.bash_profile(或~/.bash_logout或~/.profile),形成自己用户的所有可用的环境变量。
3.用户打开终端,D_proc创建bash进程。bash进程继承了D_proc的环境变量。同时,bash还会读取 ~/.bashrc 文件。至此,该bash就具有了 /etc/profile、~/.bash_profile、~/.bashrc 设置的环境变量了!

基于以上认识,下面的这些问题,将迎刃而解!

问题1/etc/profile 文件的环境变量为什么对所有用户都起效果?
回答:所有用户运行的 bash 进程都是都继承了 /etc/profile 文件设置的环境变量。所以,/etc/profile对所有用户生效!

问题2:为什么修改 /etc/profile 这个文件需要重启系统或重新登录才能生效环境变量?
回答: 因为重启系统或重新登录之后“通知”了A_proc或C_proc更新从 /etc/profile 读来的环境变量。

问题3:在图形界面,为什么修改 /etc/profile 这个文件后重新打开terminal不能生效环境变量?
回答:由范例二可知,修改 /etc/profile 这个文件后“通知”C_proc才能生效环境变量。而重新打开终端并没有重新运行C_proc,所以,不能生效!

问题4~/.bash_profile 文件为什么默认只对本用户生效,对其他用户不生效?
回答:登录某账户后,bash默认只会继承“读取”该账户home目录下的.bash_profile文件。所以,~/.bash_profile默认只对某个用户生效!

问题5:在图形界面,为什么修改 ~/.bash_profile 这个文件后重新打开terminal不能生效环境变量?
回答:由范例二可知,修改 ~/.bash_profile 这个文件后“通知”D_proc才能生效环境变量。而重新打开终端并没有重新运行C_proc,所以,不能生效!

问题6:在图形界面,为什么修改 ~/.bashrc 后重新打开terminal就能生效环境变量?
回答:在图形界面,~/.bashrc 由bash来读取,所以要使环境变量生效,必须重启进程bash。而重启terminal实际就是重启bash,这样一来就可生效了!

问题7:为什么修改 ~/.bashrc 后执行 source ~/.bashrc 也能生效环境变量?
回答:source 是 bash的builtin命令,bash将该命令解释为再次读取~/.bashrc文件,所以bash根据这个文件刷新它的环境变量了,自然就生效了!

问题8:为什么修改 ~/.bashrc 后,在bash上执行 sh ~/.bashrc,环境变量不能生效?
回答:sh是一个file,不是bash的内置命令。在运行sh的时候,sh是bash的子进程。该子进程读取~/.bashrc文件之后就退出了,而不是由bash来读的。所以,对bash来说不能生效!

# 在~/.bashrc中加入 username=hahaha 环境变量
root@study:~# source .bashrc
root@study:~# echo $username		# 使用source,环境变量生效
hahaha
root@study:~# unset username
root@study:~# echo $username

root@study:~# sh .bashrc			# 使用sh,环境变量没生效
root@study:~# echo $username

问题9:在一个bash定义的普通变量,如何将其升级为环境变量?
回答:采用 export 命令。普通变量升级为环境变量,就是要将这些普通变量存储到环境变量的存储块里export 是bash内置命令,它“通知” bash去将普通变量存储到环境变量存储块,从而实现了此功能。对于/etc/profile、~/.bash_profile、~/.bashrc这类文件可以不用加export,读取它们的程序默认会把其中的变量认定为环境变量,而对于除这类文件之外的脚本文件,若要导出环境变量,务必要加export!

问题10:为什么export环境变量后,在其他终端无法获取该变量值?
回答:export的环境变量值作用于当前执行它的bash及其子进程,其他终端不是当前的bash也不属于当前bash的子进程。因此,也就无法获取它的变量值!


总结

shell不能简单理解为bash一个进程,而应该是与bash有父子关系的一系列进程的集合

环境变量是bash进程内存空间的某个存储块!

如果要修改支持系统所有用户的环境变量,则应该修改/etc/profile文件,然后重启或重新登录即可使环境变量生效!

如果要修改支持某个用户的环境变量,则应该修改~/.bash_profile(或~/.bash_logout或~/.profile)或 ~/.bashrc文件。如果修改~/.bash_profile文件,需要重启或重新登录才能生效;如果修改~/.bashrc文件,需要重启或重新登录或重新打开终端才能生效!建议修改 ~/.bashrc 文件,因为 ~/.bash_profile 文件里边也是会 source ~/.bashrc 的!

当然了,无论修改哪个文件,若想要当前bash马上生效环境变量,source相应的被修改文件就可以了!

以上只是我对于linux环境变量的简单看法,欢迎大家批评指正!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值