文章目录
- 一、命令介绍
- 二、export 的原理
- (一)什么是进程
- (二)父子进程关系
- (三)子 shell 如何访问父 shell 的变量(export 实现原理)
- (四)父 shell 如何访问子 shell 的变量
- (五)export 作用范围
- 1. 为什么当前 shell 中执行 export 所产生的效果仅在本次会话中有效呢?
- 2. 如何设置永久的环境变
- 3. 为什么在 /etc/profile 文件中声明定义的变量是永久有效的呢?
- 三、常用选项
- 四、命令示例
- (一)列出当前所有的环境变量
- (二)声明定义环境变量
- (三)显示某个环境变量的值
一、命令介绍
export 的基本作用就是将父 shell 中的局部变量设置为环境变量,使得该变量可以在子 shell 中使用。
export 命令用于将 shell 变量输出为环境变量,或者将 shell 函数输出为环境变量。
一个变量创建时,在它之后创建的 shell 进程是不知道的,而命令 export 则可以向后面的 shell 进程传递变量的值;同样的,被调用执行的 shell 脚本是无权访问调用者定义的变量的,除非这些变量已经被显式地设置为可用,但是命令 export 可以传递变量的值给后继脚本。
二、export 的原理
(一)什么是进程
进程是一个运行着的程序,是代码的动态形式,进程有如下属性:
- 独立的内核堆栈
- 进程控制块
- 独立的存储空间
由于每个进程有自己独立的存储空间,所以进程间的的数据是不可见的,进程间的交互需要用到进程间通信。所以在一个进程内的操作通常不会影响到另一个进程的内容,也不会被另一个进程所看到。每一个 shell 都是一个独立的进程。
(二)父子进程关系
父子进程都是独立的进程,父进程可以管理子进程,这种管理主要体现在三个方面:生、管、死。
“生”
:父进程可以创建子进程。
“管”
:命令 export 的操作就属于管理。
“死”
:父进程死则子进程必须死,子进程死对父进程没有影响。
(三)子 shell 如何访问父 shell 的变量(export 实现原理)
在父 shell 中执行一个子 shell(执行命令 bash 就是执行一个子 shell),会启动一个子进程,即子 shell 是一个独立于父 shell 的进程,因此父子 shell 的存储空间是相互不可访问的(即子 shell 无法访问父 shell 中的变量),如果想让子 shell 访问父 shell 的变量就需要将该变量从父 shell 的独立存储空间复制到子 shell 的独立存储空间,子 shell 所看到的父进程的变量其实是自己进程空间的内容,而不是父进程的内容,只是该变量的名称和值与父进程相同而已。而命令 export 就是将父进程空间的内容复制到子进程的存储空间,也就是说命令 export 的作用就是将父进程的局部变量变成全局变量,即所谓变成环境变量。
(四)父 shell 如何访问子 shell 的变量
父进程可以将自己的环境变量写入到子进程的空间中,但是子进程无法将自己空间的数据写入到父进程中(至少 export
命令做不到)。那么想要让子 shell 中的变量在父 shell 可见,最好的办法就是不要成为子 shell,即只将该 shell 中的内容导入到父 shell 中(即将被调用的脚本内容复制到父 shell 中直接执行),而不单独执行该 shell 脚本文件。这样用到的导入命令是 source。
(五)export 作用范围
命令 export 可新增,修改或删除环境变量,供后续执行的程序使用,但是 export 产生的效果仅在本次会话中有效。
举例说明,将路径 /opt/au1200_rm/build_tools/bin
追加到环境变量 PATH 中:
export PATH="$PATH:/opt/au1200_rm/build_tools/bin"
1. 为什么当前 shell 中执行 export 所产生的效果仅在本次会话中有效呢?
看上述的命令可知环境变量 PATH 早已经声明和定义过,这条指令是先获取变量 PATH 的旧值再拼接新的路径最后得到新的路径字符串,再将此字符串赋值给变量 PATH,所以此条指令只是将当前进程中的栈内存的环境变量 PATH 重新赋值而已,并将其定义为可输出的变量,这样每次创建子进程时就可以将此变量复制到子进程的内存空间中。
当进程结束后,内存空间被释放回收了,所以属于该进程的变量自然也被回收了。当再次创建 shell 进程时,加载到新进程内存空间的环境变量 PATH 是从配置文件读取的,相当于说环境变量 PATH 恢复原值了。
2. 如何设置永久的环境变
在 /etc/profile
文件中声明定义环境变量,那么每次创建进程的时候,就都可以获取到该变量的值。
[root@htlwk0001host ~]# vi /etc/profile
在里面加入:
export PATH="$PATH:/opt/au1200_rm/build_tools/bin"
修改配置文件 /etc/profile
是对所有的用户有效,建议修改用户家目录下的配置文件 .bashrc
或 .bash_profile
,这两个配置文件仅对当前登录用户有效。
注:在全局配置文件 /etc/profile
中,如果把变量定义成上述的语句,那么第一个进程创建时变量 $PATH
的取值必然为空,因为没有父进程,所以谈不上复制父进程的全局变量。第一个进程创建时先读取 /etc/profile
文件,此时第一个进程的内存中根本不存在变量 $PATH
,所以何来“旧值”替换。
3. 为什么在 /etc/profile 文件中声明定义的变量是永久有效的呢?
我们每次打开一个命令窗口,就是创建一个 shell 进程,而且这个进程是父进程,会先读取 /etc/profile 文件,所以每次创建进程的时候都可以获取到 /etc/profile 文件里面的变量。
子进程不会读取任何的配置文件,子进程的栈内存中的变量都是从父进程复制过来的,当然必须是标记为 “export” 的变量才会复制到子进程的内存空间中。
三、常用选项
选项 | 说明 |
---|---|
-f | 代表[变量名称]中为函数名称 |
-n | 删除指定的变量。变量实际上并未删除,只是不会输出到后续指令的执行环境中 |
-p | 列出所有的 shell 赋予程序的环境变量 |
四、命令示例
(一)列出当前所有的环境变量
[root@htlwk0001host ~]# export -p
declare -x DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/0/bus"
declare -x HISTCONTROL="ignoredups"
declare -x HISTSIZE="1000"
(二)声明定义环境变量
[root@linuxcool ~]# export MYENV=7
注意:仅在当前登录会话有效,退出后就失效了。
(三)显示某个环境变量的值
[root@htlwk0001host ~]# echo $HOME
/root