一、环境变量
登录系统后会启动一个shell,如果在这里运行bash则会启动一个新的shell,这个新的shell就是子shell,而之前的shell就是父shell。我们在运行脚本时也会创建一个新的子shell,当程序结束时又回到父shell中。
全局环境变量对于shell会话和所有生成的字shell都是可见的。局部变量则只对创建它们的shell可见。创建全局环境变量的方法是先创建一个局部环境变量,然后再把它导出(export)到全局环境中。
$ my_variable="I am Gobal now"
$ export my_variable
局部环境变量只能在定义它们的进程中可见。
父shell设定的全局环境变量在其子进程中也都是可见的。修改或删除子shell中的全局环境变量并不会影响到父shell中的该环境变量。
我们可以用. 或source 命令,不开启子shell而运行脚本,从而使变量生效。比如修改完配置文件 ~/.bashrc,可以用 source ~/.bashrc或者. ~/.bashrc方式重新读取。(source命令的作用是在当前bash环境下读取并执行文件中的命令,source命令通常用命令“.”来替代)
二、关于shell的一些配置文件
全局配置
/etc/profile
/etc/profile.d/*.sh
/etc/bashrc
个人配置
~/.bash_profile
~/.bashrc
~/.bash_login
~/.profile
大多数Linux发行版只用这四个启动文件中的一到两个。
这些环境变量会在每次启动bash shell会话时生效,shell会按照下列顺序,运行第一个被找到的文件,余下的则被忽略。
~/.bash_profile
~/.bash_login
~/.profile
注意这个列表中并没有~/.bashrc文件,这是因为该文件通常通过其他文件运行。
三、关于交互式shell与非交互式shell
交互式shell就是在终端上执行,shell等用待用户输入,输入完成立即执行用户提交的命令,这种模式因为用户与shell交互了,所以是交互式shell。 一般我们登录,执行命令,exit或logout退出shell,这种shell就是交互式shell。
非交互式shell,比如以脚本的方式执行,一行一行执行,执行完所有行,shell终止。这个过程没有与用户交互,这就是非交互式shell。
四、登录shell与非登录shell
登录shell就是需要用户名和密码才能进入的shell(或通过–login选项生成的shell,比如:su –login username)
非登录shell就是不需要输入用户名和密码就可打开的shell,如直接输入bash打开一个子shell, 在图形界面打开一个终端(terminal)窗口也是一个非登录shell。
五、读取配置环境变量文件的顺序
- 登录shell
登录shell会从5个不同的启动文件里读取命令:
/etc/profile
~/.bash_profile
~/.bashrc
~/.bash_login
~/.profile
/etc/profile文件是系统上默认的bash shell的主启动文件,系统上的每个用户登录时都会执行这个启动文件。另外4个启动文件是针对用户的,会在每次启动bash shell会话时生效。
shell会按照下列顺序,运行第一个被找到的文件,余下的则被忽略。
~/.bash_profile
~/.bash_login
~/.profile
注意这个列表中并没有~/.bashrc文件,这是因为该文件通常通过其他文件运行。
- 交互式shell
如果bash是作为交互式shell启动的,它就不会访问/etc/profile文件,只会检查用户HOME目录中的.bashrc文件。
- 非交互式shell
系统执行shell脚本时用的就是这种shell。不同的地方在于它没有命令行提示符。当shell启动一个非交互式shell进程时,它会检查BASH_ENV环境变量来查看要执行的启动文件。如果有指定的文件,shell会执行该文件里的命令,这通常包括shell脚本变量设置。
如果BASH_ENV变量没有设置,shell脚本到哪里去获得它们的环境变量呢?别忘了有些shell脚本是通过启动一个shell来执行的。子shell可以继承父shell导出过的变量。
六、环境变量持久化
-
系统级变量
对于全局变量来说,修改/etc/profile文件不是个好主意,因为如果升级了所用的发行版,这个文件也会跟着更新,那定制过的变量设置可就都没有了。
最好是在/etc/profile.d目录中创建一个以sh结尾的文件,把所有新的或修改过的全局环境变量设置放在这个文件中。 -
用户级变量
~/.bashrc文件