目录
- 一、概述
- 二、什么是环境变量
- 2.1 全局环境变量
- 2.2 局部环境变量
- 三、设置用户自定义变量
- 3.1 设置局部用户自定义变量
- 3.2 设置全局环境变量
- 3.3 删除环境变量
- 四、默认的 shell 环境变量
- 五、
- 5.1 设置 PATH 环境变量
- 5.2
一、概述
Linux 系统中,很多程序和脚本通过环境变量来获取系统信息、存储临时数据和配置信息,了解去哪里设置相应的环境变量很重要。
本文总结了Linux 环境变量:它们存储在哪里、如何使用,以及如何创建自己的环境变量,最后会以数组变量的用法作结。
二、什么是环境变量
环境变量允许在内存中存储数据,以便 shell 中运行的程序或脚本能够轻松访问到这些数据。这也是存储持久数据的一种简便方法。bash shell 中有两种环境变量:
- 全局变量
- 局部变量
2.1 全局环境变量
全局环境变量对于 shell 会话和所有生成的子 shell 都是可见的。局部环境变量则只对创建它的 shell 可见。如果程序创建的子 shell 需要获取父 shell 信息,那么全局环境变量就能派上用场了。
系统环境变量基本上会使用全大写字母,以区别于用户自定义的环境变量。可以使用env
命令或printenv
命令来查看全局变量:>wkd@ubuntu:~$ printenv XDG_SESSION_ID=4 SHELL=/bin/bash TERM=xterm-256color SSH_CLIENT=192.168.2.100 2132 22 SSH_TTY=/dev/pts/10 USER=wkd JRE_HOME=/opt/jvm/jdk1.8.0_271/jre PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games MAIL=/var/mail/wkd QT_QPA_PLATFORMTHEME=appmenu-qt5 PWD=/home/wkd JAVA_HOME=/opt/jvm/jdk1.8.0_271 LANG=en_US.UTF-8 HOME=/home/wkd SHLVL=2 UNITY_PANEL_TRAY_DISABLE= LOGNAME=wkd CLASSPATH=.:/opt/jvm/jdk1.8.0_271/lib:/opt/jvm/jdk1.8.0_271/jre/lib LESSOPEN=| /usr/bin/lesspipe %s XDG_RUNTIME_DIR=/run/user/1000 LESSCLOSE=/usr/bin/lesspipe %s %s OLDPWD=/home/lu _=/usr/bin/printenv wkd@ubuntu:~$
printenv
命令可以显示指定的环境变量的值:wkd@ubuntu:~$ printenv HOME /home/wkd wkd@ubuntu:~$
echo
命令也可以显示变量的值。在引用某个环境变量时,必须在该变量名前加上美元符号($
):wkd@ubuntu:~$ echo $HOME /home/wkd wkd@ubuntu:~$
2.2 局部环境变量
局部环境变量只能在定义它的进程中可见。set 命令可以显示特定进程的所有环境变量,既包括局部变量、全局变量,也包括用户自定义变量,下面演示set命令使用,由于输出太多,使用
grep
过滤,只显示带HOME的环境变量:wkd@ubuntu:~$ set | grep HOME HOME=/home/wkd JAVA_HOME=/opt/jvm/jdk1.8.0_271 JRE_HOME=/opt/jvm/jdk1.8.0_271/jre wkd@ubuntu:~$
三、设置用户自定义变量
3.1 设置局部用户自定义变量
启动 bash shell(或者执行 shell 脚本)之后,就能创建仅对该 shell 进程可见的局部用户自定义变量。格式是:
变量名=变量值
,值可以是数值或字符串。读取变量值需要使用美元符号$
下面的交互式shell的演示:wkd@ubuntu:~$ my_var=1234a wkd@ubuntu:~$ echo $my_var 1234a wkd@ubuntu:~$
如果用于赋值的字符串包含空格,则必须用
单引号
或双引号
来界定该字符串的起止:wkd@ubuntu:~$ my_var="hello world" wkd@ubuntu:~$ echo $my_var hello world wkd@ubuntu:~$
如果没有引号,则 bash shell 会将下一个单词①( World)视为另一个要执行的命令。
注意,你定义的局部变量用的是小写字母,而系统环境变量用的都是大写字母。在变量名、等号和值之间没有空格。
局部变量可以通过
set
命令看到,而通过env
或printenv
命令无法看到:wkd@ubuntu:~$ set | grep my_var my_var='hello world' wkd@ubuntu:~$ env | grep my_var wkd@ubuntu:~$ printenv | grep my_var
3.2 设置全局环境变量
全局环境变量在设置该变量的父进程所创建的子进程中都是可见的。
创建方法:先创建局部变量,然后再使用export
导出到全局环境中。
用前面的my_var
变量举例,前面设置成局部变量 ,用env
命令看不到,如果导出到全局环境中,env
命令就可以查看了:wkd@ubuntu:~$ export my_var wkd@ubuntu:~$ env | grep my_var my_var=hello world wkd@ubuntu:~$
在现实中设置全局变量,常设置变量和导出变量放在同一语句,如:
export my_var="hello world"
。
全部变量在子shell中可见,但子 shell 无法修改父 shell 中全局环境变量的值,见如下例子:
3.3 删除环境变量
在环境变量名(没有加
$
)前加上unset
,可以删除该环境变量:
和修改变量一样,在子 shell 中删除全局变量后,无法将效果反映到父 shell 中。
四、默认的 shell 环境变量
在默认情况下, bash shell 会用一些特定的环境变量来定义系统环境。
这些变量在你的 Linux系统中都已设置好,只管放心使用就行了。由于 bash shell 源自最初的 Unix Bourne shell,因此也保留了 Unix Bourne shell 中定义的那些环境变量。
下表列出了 bash shell 与 Unix Bourne shell 兼容的环境变量:
变量 | 描述 |
---|---|
CDPATH | 以冒号分隔的目录列表,作为 cd 命令的搜索路径 |
HOME | 当前用户的主目录 |
IFS | shell 用来将文本字符串分割成字段的若干字符 |
当前用户收件箱的文件名( bash shell 会检查这个文件来确认有没有新邮件) | |
MAILPATH | 以冒号分隔的当前用户收件箱的文件名列表( bash shell 会检查列表中的每个文件来确认有没有新邮件) |
OPTARG | 由 getopt 命令处理的最后一个选项参数 |
OPTIND | 由 getopt 命令处理的最后一个选项参数的索引 |
PATH | shell 查找命令时使用的目录列表,以冒号分隔 |
PS1 | shell 命令行的主提示符 |
PS2 | shell 命令行的次提示符 |
除了默认的 Bourne 环境变量, bash shell 还提供一些自有的变量,不是所有的默认环境变量都会在 set 命令的输出中列出。如果用不到,默认环境变量并不要求必须有值:
变量 | 描述 |
---|---|
BASH | bash shell 当前实例的完整路径名 |
BASH_ALIASES | 关联数组,包含当前已设置的别名 |
BASH_ARGC | 数组变量,包含传入函数或 shell 脚本的参数个数 |
BASH_ARCV | 数组变量,包含传入函数或 shell 脚本的参数 |
BASH_ARCV0 | 包含 shell 的名称或 shell 脚本的名称(如果在脚本中使用的话) |
BASH_CMDS | 关联数组,包含 shell 已执行过的命令的位置 |
BASH_COMMAND | 正在执行或将要执行的 shell 命令 |
BASH_COMPAT | 指定 shell 兼容级别的值 |
BASH_ENV | 如果设置的话, bash 脚本会在运行前先尝试运行该变量定义的启动文件 |
BASH_EXECUTION_STRING | 使用 bash 命令的-c 选项传递过来的命令 |
BASH_LINENO | 数组变量,包含当前正在执行的 shell 函数在源文件中的行号 |
BASH_LOADABLE_PATH | 以冒号分隔的目录列表, shell 会在其中查找可动态装载的内建命令 |
BASH_REMATCH | 只读数组变量,在使用正则表达式的比较运算符=~进行肯定匹配( positive match)时,包含整个模式及子模式所匹配到的内容 |
BASH_SOURCE | 数组变量,包含当前正在执行的 shell 函数所在的源文件名 |
BASH_SUBSHELL | 当前子 shell 环境的嵌套级别(初始值是 0) |
BASH_VERSINFO | 数组变量,包含 bash shell 当前实例的主版本号和次版本号 |
BASH_VERSION | bash shell 当前实例的版本号 |
BASH_XTRACEFD | 如果设置为有效的文件描述符( 0、 1、 2),则’set -x’调试选项生成的跟踪输出可被重定向。通常用于将跟踪信息输出到文件中 |
BASHOPTS | 当前启用的 bash shell 选项 |
BASHPID | 当前 bash 进程的 PID |
CHILD_MAX | 设置 shell 能够记住的已退出子进程状态的数量 |
COLUMNS | bash shell 当前实例所用的终端显示宽度 |
COMP_CWORD | 变量 COMP_WORDS 的索引,其中包含当前光标的位置 |
COMP_LINE | 当前命令行 |
COMP_POINT | 相对于当前命令起始处的光标位置索引 |
COMP_KEY | 用来调用 shell 函数补全功能的最后一个按键 |
COMP_TYPE | 一个整数值,指明了用以完成 shell 函数补全所尝试的补全类型 |
COMP_WORDBREAKS | Readline 库中用于单词补全的分隔符 |
COMP_WORDS | 数组变量,包含当前命令行所有单词 |
COMPREPLY | 数组变量,包含由 shell 函数生成的可能的补全代码 |
COPROC | 数组变量,包含用于匿名协程 I/O 的文件描述符 |
DIRSTACK | 数组变量,包含目录栈的当前内容 |
EMACS | 设置为’t’时,表明 emacs shell 缓冲区正在工作,行编辑功能被禁止 |
EPOCHREALTIME | 包含自 Unix 纪元时( 1970 年 1 月 1 日 00:00:00 UTC)以来的秒数,包括微秒 |
EPOCHSECONDS | 包含自 Unix 纪元时( 1970 年 1 月 1 日 00:00:00 UTC)以来的秒数,不包括微秒 |
ENV | 如果设置,则会在 bash shell 脚本运行之前先执行已定义的启动文件(仅当 bash shell 以 POSIX 模式被调用时) |
EUID | 当前用户的有效用户 ID(数字形式) |
EXECIGNORE | 以冒号分隔的过滤器列表,在使用 PATH 搜索命令时,用于决定要忽略的可执行文件(比如共享库文件) |
FCEDIT | 供 fc 命令使用的默认编辑器 |
FIGNORE | 在进行文件名补全时可以忽略后缀名列表,以冒号分隔 |
FUNCNAME | 当前正在执行的 shell 函数的名称 |
FUNCNEST | 当设置成非 0 值时,表示所允许的函数最大嵌套级数(一旦超出,当前命令即被终止) |
GLOBIGNORE | 以冒号分隔的模式列表,定义了在进行文件名扩展时可以忽略的一组文件名 |
GROUPS | 数组变量,包含当前用户的属组 |
histchars | 控制历史记录扩展,最多可有 3 个字符 |
HISTCMD | 当前命令在历史记录中的编号 |
HISTCONTROL | 控制哪些命令留在历史记录列表中 |
HISTFILE | 保存 shell 历史记录的文件名(默认是.bash_history) |
HISTFILESIZE | 历史记录文件( history file)能保存的最大命令数量 |
HISTIGNORE | 以冒号分隔的模式列表,用于决定忽略历史文件中的哪些命令 |
HISTSIZE | 能写入历史记录列表( history list)的最大命令数量 |
HISTTIMEFORMAT | 如果设置且不为空,则作为格式化字符串,用于打印 bash 历史记录中命令的时间戳 |
HOSTFILE | shell 在补全主机名时读取的文件名 |
HOSTNAME | 当前主机的名称 |
HOSTTYPE | 字符串,用于描述当前运行 bash shell 的机器 |
IGNOREEOF | shell 在退出前必须连续接收到的 EOF 字符数量(如果该值不存在,则默认为 1) |
INPUTRC | Readline 的初始化文件名(默认为.inputrc) |
INSIDE_EMACS | 仅当进程在 Emacs 编辑器的缓冲区中运行时才设置,并且可以禁用行编辑(行编辑的禁用也取决于 TERM 变量的值) |
LANG | shell 的语言环境种类( locale category) |
LC_ALL | 定义语言环境种类,能够覆盖 LANG 变量 |
LC_COLLATE | 设置字符串排序时采用排序规则 |
LC_CTYPE | 决定如何解释出现在文件名扩展和模式匹配中的字符 |
LC_MESSAGES | 决定在解释前面带有$的双引号字符串时采用的语言环境设置 |
LC_NUMERIC | 决定格式化数字时采用的语言环境设置 |
LC_TIME | 决定格式化日期和时间时采用的语言环境设置 |
LINENO | 当前正在执行的脚本语句的行号 |
LINES | 定义了终端上可见的行数 |
MACHTYPE | 用“CPU–公司–系统”( CPU-company-system)格式定义的系统类型 |
MAILCHECK | shell 应该多久检查一次新邮件(以秒为单位,默认为 60 秒) |
MAPFILE | 数组变量,当未指定数组变量作为参数时,其中保存了 mapfile 所读入的文本 |
OLDPWD | shell 先前使用的工作目录 |
OPTERR | 如果设置为 1,则 bash shell 会显示 getopts 命令产生的错误 |
OSTYPE | 定义了 shell 所在的操作系统 |
PIPESTATUS | 数组变量,包含前台进程的退出状态 |
POSIXLY_CORRECT | 如果设置的话, bash 会以 POSIX 模式启动 |
PPID | bash shell 父进程的 PID |
PROMPT_COMMAND | 如果设置的话,在显示命令行主提示符之前执行该命令 |
PROMPT_DIRTRIM | 用来定义使用提示符字符串\w 和\W 转义时显示的拖尾( trailing)目录名的数量(使用一组英文句点替换被删除的目录名) |
PS0 | 如果设置的话,指定了在输入命令之后、执行命令之前由交互式 shell 显示的内容 |
PS3 | select 命令的提示符 |
PS4 | 在命令行之前显示的提示符(如果使用了 bash 的-x 选项的话) |
PWD | 当前工作目录 |
RANDOM | 返回一个 0~ 32 767 的随机数(对该变量的赋值可作为随机数生成器的种子) |
READLINE_LINE | 当使用 bind –x 命令时,保存 Readline 缓冲区的内容 |
READLINE_POINT | 当使用 bind –x 命令时,指明了 Readline 缓冲区内容插入点的当前位置 |
REPLY | read 命令的默认变量 |
SECONDS | 自 shell 启动到现在的秒数(对其赋值会重置计数器) |
SHELL | bash shell 的完整路径名 |
SHELLOPTS | 以冒号分隔的已启用的 bash shell 选项 |
SHLVL | shell 的层级,每启动一个新的 bash shell,该值增加 1 |
TIMEFORMAT | 指定了 shell 的时间显示格式 |
TMOUT | select 命令和 read 命令在无输入的情况下等待多久(以秒为单位,默认值为 0,表示一直等待) |
TMPDIR | 目录名,保存 bash shell 创建的临时文件 |
UID | 当前用户的真实用户 ID(数字形式) |
五、
5.1 设置 PATH 环境变量
PATH
环境变量定义了用于查找命令和程序的目录。当外部命令或程序所在的位置包含在PATH
变量中,那么不不使用绝对路径,shell 也可以找到该路径,否则,会报错command not found
。
下面是Ubuntu 系统的PATH
环境变量的值,目录之间以冒号分隔:wkd@ubuntu:~$ echo $PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
在
PATH
环境变量新增一个路径,只需引用原来的 PATH 值,添加冒号(:
),然后再使用绝对路径输入新目录即可,如:PATH=$PATH:/home/wkd/cmd
。
对于 PATH 变量的修改只能持续到退出或重启系统。下一节会介绍如何永久保持环境变量的改动。
5.2
如果文章有帮助的话,点赞👍、收藏⭐,支持一波,谢谢 😁😁😁