[linux] 环境变量
Linux环境变量
bash shell 使用环境变量 来存储 shell会话和工作环境的相关信息。
环境变量允许在内存
中存储数据,使得shell中运行的程序或脚本能够轻松访问到这些数据。
因此,环境变量也是一种数据持久化
的方式。
bash shell提供了2种环境变量:全局环境变量
和局部环境变量
局部环境变量
所谓局部环境变量,就是只对定义它的shell会话可见。
Linux系统也默认定义了一部分标准的局部环境变量。
查看局部环境变量
Linux无法只查看系统有哪些局部变量。
Linux提供了set
命令,可以显示特定进程的所有环境变量(包括全局变量、局部变量、用户自定义变量和局部shell函数);
1 | root@smith-PC:~# set |
设置局部环境变量
用户可以直接在shell中设置变量,这些变量被称为用户自定义局部变量
。
使用变量名=值
形式定义并赋值一个变量,值可以是数值
或字符串
;
建议1:使用小写字母定义局部变量,避免与系统环境变量同名;
注意1:在变量名、=和值之间不能有空格;
注意2:当用于赋值变量的字符串中含有空格时,需使用引号(单引号/双引号)包裹该字符串,以避免系统将空格后的单词误解析为单独的指令;
1 | root@smith-PC:~# var0=Hellodibian |
父子进程无法访问各自定义的局部变量
局部变量只能在定义它的进程中使用,其他进程无法访问到;
- 子进程访问父进程的局部变量
1
2
3
4
5
6
7
8
9
10
11root@smith-PC:~# num=99
root@smith-PC:~# echo $num
99
root@smith-PC:~# bash
root@smith-PC:~# echo $num
root@smith-PC:~# exit
exit
root@smith-PC:~# echo $num
99
root@smith-PC:~# - 父进程访问子进程的局部变量因此,只能通过定义全局变量来让父子进程通信。
1
2
3
4
5
6
7
8
9root@smith-PC:~# bash
root@smith-PC:~# var=99
root@smith-PC:~# echo $var
99
root@smith-PC:~# exit
exit
root@smith-PC:~# echo $var
root@smith-PC:~#
全局环境变量
所谓全局环境变量,就是对所有shell会话均可见。
全局环境变量通常使用全大写,以区别于用户自定义环境变量。
查看全局环境变量
使用env
或printenv
来查看全局环境变量。
1. 查看所有全局环境变量
1 | root@smith-PC:~# env |
1 | root@smith-PC:~# printenv |
2. 查看指定全局环境变量
查看指定全局变量时,需要用printenv
,不能用env
1 | root@smith-PC:~# printenv HOME |
3. 引用指定全局环境变量
可以使用$变量名
的方式,获取变量的值。
1 | root@smith-PC:~# echo $HOME |
$变量名
也可以作为命令的参数来使用。
1 | root@smith-PC:~# ls $HOME |
设置全局环境变量
子进程无法访问到父进程的局部变量,因此可以通过创建全局环境变量使得该变量可见;
创建全局环境变量的方法:
- 先创建局部变量
- 再导出到全局环境中:使用export命令进行导出
1
2
3
4
5
6
7
8
9
10root@smith-PC:~# var_parent=hello
root@smith-PC:~# export var_parent
root@smith-PC:~# bash
root@smith-PC:~# echo $var_parent
hello
root@smith-PC:~# exit
exit
root@smith-PC:~# echo $var_parent
hello
root@smith-PC:~#
简化命令:export var_parent=hello
子进程也可以对父进程的全局变量进行修改,但不会影响到父进程的全局变量的值,仅在子进程中有效。
1 | root@smith-PC:~# export var_parent=hello |
此时,使用set
命令查看环境变量是,就可以看到其中有一条var_parent=hello
,就是刚刚创建的,当关闭该shell并重启一个shell时再查看,就会被自动删除。
env / printenv / set的区别
特征 | env | printenv | set |
---|---|---|---|
查看变量类型 | 全局变量 局部变量 用户自定义变量 局部shell函数 |
全局变量 | 全局变量 |
是否可排序 | 按字母对结果排序 | 不可排序 | 不可排序 |
删除环境变量
使用unset 变量名
可以删除环境变量,同理,子进程删除环境变量后,不影响父进程。
1 | root@smith-PC:~# export var_parent=hello |
默认的全局环境变量
bash shell 会预先设定一些环境变量来定义系统环境,由于bash shell与Unix Bourne shell兼容,因此保留了其定义的环境变量。
不是所有默认环境变量都在set命令中输出,若没有用到,默认环境变量并不要求必须有值。
系统使用的环境变量取决于bash shell
版本,部分变量仅在bash shell 5
或更高版本可用,可通过bash --version
命令查看。
PATH环境变量
查看PATH环境变量
在shell中,我们通常会输入一个外部命令(如todesk),此时shell会搜索系统,从中找到对应的程序。
环境变量PATH
就定义了用于查找命令和程序的目录。
使用$PATH
命令查看PATH环境变量内容:
1 | root@smith-PC:~# $PATH |
PATH
以:
分隔多个目录,shell会在其中按顺序查找命令或程序。若这些目录中找不到输入的命令或程序,则会产生错误信息:
1 | root@smith-PC:~# todesk |
添加PATH环境变量(临时)
部分应用程序的可执行文件目录可能不在PATH中,此时可以:
- 在shell中输入该程序的全路径;
- 将该程序的所在目录的绝对路径添加到PATH环境变量中,格式为:
PATH=$PATH:新目录的绝对路径
,此时就可以直接输入程序名执行,但这种方式只是暂时性的,当退出或重启系统就会失效。1
2
3
4
5
6
7
8
9
10
11root@smith-PC:~# ls /opt/apps
app1 app2
root@smith-PC:~# $PATH
bash: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:
root@smith-PC:~# PATH=$PATH:/opt/apps
root@smith-PC:~# $PATH
bash: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/opt/apps
root@smith-PC:~# app1
爸爸的爸爸叫爷爷!
root@smith-PC:~# app2
爸爸的妈妈叫奶奶!
添加PATH环境变量(持久化)
bash与启动文件
当我们登录成功后启动bash shell
时,bash
会在几个文件中查找命令,这些文件称为启动文件或环境文件;
bash进程选择那些启动文件,取决于用户启动bash shell的方式。而启动bash shell共有3种方式:
方式 | 文件类型 | 文件路径 |
---|---|---|
登录时作为默认登录shell | 系统级 | /etc/profile |
用户级 | $HOME/.bash_profile $HOME/.bashrc $HOME/.bash_login $HOME/.profile |
|
作为交互式shell,通过生成子shell启动 | 用户级 | $HOME/.bashrc |
作为运行脚本的非交互式shell | ||
TODO-方式1:登录时作为默认登录shell
当用户登录Linux
系统时,bash shell
会作为登录shell
启动;登录shell
通常从5个启动文件中读取命令:
- /etc/profile(默认)
- $HOME/.bash_profile
- $HOME/.bashrc
- $HOME/.bash_login
- $HOME/.profile
TODO-方式2:作为交互式shell,通过生成子shell启动
TODO-方式3:作为运行脚本的非交互式shell
环境变量持久化
上述提到的启动文件,就可以帮助我们实现永久性保存全局变量或局部变量;
对于全局环境变量:可以放在/etc/profile
中,但若系统更新,该文件也会更新,因此不推荐。建议在/etc/profile.d
目录中创建一个.sh
文件,将所有新增或修改的全局环境变量都放在该文件中;
对于用户环境变量:推荐写在$HOME/.bashrc
文件中。
数组变量
环境变量也可以添加数组,用来存储多个值,既可以单独引用,也可以整体引用。
但是,数组在Linux使用频率相对较低,有可能不便于移植到其他shell环境中。
规则 | 命令 | 备注 |
---|---|---|
设置数组环境变量 | 变量名=(值1 值2 值3) |
值与值之间用空格隔开 |
修改指定索引元素 | 变量名[索引]=值 |
|
删除指定索引元素 | unset 变量名[索引] |
不建议使用 |
删除整个数组 | unset 变量名 |
|
引用首个数组元素 | echo $变量名 |
|
引用指定索引元素 | echo $(变量名[索引]) |
|
引用整个数组 | echo $(变量名[*]) |