环境变量:环境变量是在程序及其子程序中全局可用的,常常用来储存像默认的文本编辑器或者浏览器,以及可执行文件的路径等等这样的变量信息。环境变量的名称是区分大小写的,且通常以大写的形式命名 ( MYVAR1, MYVAR2... )
与shell变量不同,Shell 变量仅在当前 Shell 中可用,可以用来存储当前用户的 ID 等信息。
一、读取已设置的环境变量
1、env
该命令可以在自定义的环境中运行程序,并且不需要改变当前的环境。
当不带参数使用 env
命令时,它会打印出当前的环境变量列表。
2、printenv
可以打印出所有的或者指定的环境变量
printenv和env的区别:
使用 printenv
命令,可以请求单个变量的值:
$ printenv SHELL /bin/bash $ printenv HOME /home/alvin $ printenv MYVAR lxlinux.net
env
命令可通过将一组变量传递给命令来修改程序运行的环境
env MYVAR=lxlinux.net command_to_run command_options
printenv
与 env
命令只能打印出环境变量,而如果你想打印出所有变量或者 Shell 函数的列表,你可以使用 set
指令。
3、set
令可以设置或者删除 Shell 变量。当不带参数使用 set
命令时,它将打印出包括环境变量与 Shell 变量在内的所有变量以及 Shell 函数的列表。
4、export
显示当前系统定义的所有环境变量
# export declare -x EDITOR="vim" declare -x USER="root" ..... declare -x XDG_RUNTIME_DIR="/run/user/0" declare -x XDG_SESSION_ID="3"
echo $PATH命令输出当前的PATH环境变量的值
#echo $PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
其中PATH变量定义了运行命令的查找路径,以冒号:分割不同的路径,使用export定义的时候可加双引号也可不加。
二、设置的环境变量
1、Linux 系统中可以设置环境变量的命令有以下几种:
set
— 设置或者取消 Shell 变量。当不带参数使用 set
命令时,它将打印出包括环境变量与 Shell 变量在内的所有变量以及 Shell 函数的列表
unset
— 删除 Shell 变量以及环境变量
export
— 该命令可以设置环境变量
辨别 Shell 变量和环境变量:
先从在当前会话中定义一个 Shell 变量开始:
tv=aiqiyi
printenv查看没输出为shell变量
echo $tv aiqiyi printenv | grep tv
export设置并printenv 查看变量有输出
export tv=aiqiyi printenv | grep tv tv=aiqiyi
但是以 export 方式创建的环境变量只能用于当前会话,如果你打开一个新的 Shell 会话,或者退出登陆,所有的变量都将会丢失。
我们也可以将环境变量还原为 Shell 变量,或者将其完全删除:
tv变量被定义为环境变量,我们可以通过输入以下代码将其还原为 Shell 变量:
export -n tv printenv | grep tv echo $tv aiqiyi
这样,tv 变量就不再是环境变量了,但依然还是 Shell 变量。
无论是 Shell 变量还是环境变量,想要完全删除变量,都可以使用 unset
命令来删除:
unset tv
在大多数 Linux 发行版中,当启动一个新的会话时,一般都会从以下文件中读取环境变量:
/etc/environment
— 使用此文件来设置系统范围内可用的环境变量。
/etc/profile
— 每当 bash 登录 Shell 时,都会加载此文件中设置的变量。
~/.bashrc
— 每个用户特定的 Shell 配置文件。例如, 如果你使用的是Bash,就可以在其中声明变量。
如果要将新的环境变量加载到当前的 Shell 会话中,可以使用source命令
source ~/.bashrc
2、设置临时环境变量 export
Shell 变量作为全局变量使用,可以使用 export
指令:
使用export命令直接修改PATH的值,配置MySQL进入环境变量的方法:
export PATH=/home/uusama/mysql/bin:$PATH #或者把PATH放在前面 export PATH=$PATH:/home/uusama/mysql/bin
注意事项:
- 生效时间:立即生效
- 生效期限:当前终端有效,窗口关闭后无效
- 生效范围:仅对当前用户有效
- 配置的环境变量中不要忘了加上原来的配置,即$PATH部分,避免覆盖原来配置
3、设置永久环境变量
写入 ~/.bashrc
通过修改用户目录下的~/.bashrc文件进行配置:
vim ~/.bashrc # 在最后一行加上 export PATH=$PATH:/home/uusama/mysql/bin
注意事项:
- 生效时间:使用相同的用户打开新的终端时生效,或者手动source ~/.bashrc生效
- 生效期限:永久有效
- 生效范围:仅对当前用户有效
- 如果有后续的环境变量加载文件覆盖了PATH定义,则可能不生效
写入 ~/.bash_profile
和修改~/.bashrc文件类似,也是要在文件最后加上新的路径即可:
vim ~/.bash_profile # 在最后一行加上 export PATH=$PATH:/home/uusama/mysql/bin
注意事项:
- 生效时间:使用相同的用户打开新的终端时生效,或者手动source ~/.bash_profile生效
- 生效期限:永久有效
- 生效范围:仅对当前用户有效
- 如果没有~/.bash_profile文件,则可以编辑~/.profile文件或者新建一个
写入 /etc/bashrc
该方法是修改系统配置,需要管理员权限(如root)或者对该文件的写入权限:
# 如果/etc/bashrc文件不可编辑,需要修改为可编辑 chmod -v u+w /etc/bashrc vim /etc/bashrc # 在最后一行加上 export PATH=$PATH:/home/uusama/mysql/bin
注意事项:
- 生效时间:新开终端生效,或者手动source /etc/bashrc生效
- 生效期限:永久有效
- 生效范围:对所有用户有效
写入 /etc/profile
该方法修改系统配置,需要管理员权限或者对该文件的写入权限,和vim /etc/bashrc类似:
# 如果/etc/profile文件不可编辑,需要修改为可编辑 chmod -v u+w /etc/profile vim /etc/profile # 在最后一行加上 export PATH=$PATH:/home/uusama/mysql/bin
注意事项:
- 生效时间:新开终端生效,或者手动source /etc/profile生效
- 生效期限:永久有效
- 生效范围:对所有用户有效
写入 /etc/environment
该方法是修改系统环境配置文件,需要管理员权限或者对该文件的写入权限:
# 如果/etc/bashrc文件不可编辑,需要修改为可编辑 chmod -v u+w /etc/environment vim /etc/profile # 在最后一行加上 export PATH=$PATH:/home/uusama/mysql/bin
注意事项:
- 生效时间:新开终端生效,或者手动source /etc/environment生效
- 生效期限:永久有效
- 生效范围:对所有用户有效
三、Linux环境变量加载原理解析
上面列出了环境变量的各种配置方法,那么Linux是如何加载这些配置的呢?是以什么样的顺序加载的呢?
特定的加载顺序会导致相同名称的环境变量定义被覆盖或者不生效。
环境变量的分类
环境变量可以简单的分成用户自定义的环境变量以及系统级别的环境变量。
- 用户级别环境变量定义文件:~/.bashrc、~/.profile(部分系统为:~/.bash_profile)
- 系统级别环境变量定义文件:/etc/bashrc、/etc/profile(部分系统为:/etc/bash_profile)、/etc/environment
另外在用户环境变量中,系统会首先读取~/.bash_profile(或者~/.profile)文件,如果没有该文件则读取~/.bash_login,根据这些文件中内容再去读取~/.bashrc。
Linux加载环境变量的顺序如下:
系统环境变量 -> 用户自定义环境变量 /etc/environment -> /etc/profile -> ~/.profile
打开/etc/profile文件你会发现,该文件的代码中会加载/etc/bash.bashrc文件,然后检查/etc/profile.d/目录下的.sh文件并加载。
# /etc/profile: system-wide .profile file for the Bourne shell (sh(1)) # and Bourne compatible shells (bash(1), ksh(1), ash(1), ...). if [ "$PS1" ]; then if [ "$BASH" ] && [ "$BASH" != "/bin/sh" ]; then # The file bash.bashrc already sets the default PS1. # PS1='\h:\w\$ ' if [ -f /etc/bash.bashrc ]; then . /etc/bash.bashrc fi else if [ "`id -u`" -eq 0 ]; then PS1='# ' else PS1='$ ' fi fi fi if [ -d /etc/profile.d ]; then for i in /etc/profile.d/*.sh; do if [ -r $i ]; then . $i fi done unset i fi
其次再打开~/.profile文件,会发现该文件中加载了~/.bashrc文件。
# if running bash if [ -n "$BASH_VERSION" ]; then # include .bashrc if it exists if [ -f "$HOME/.bashrc" ]; then . "$HOME/.bashrc" fi fi # set PATH so it includes user's private bin directories PATH="$HOME/bin:$HOME/.local/bin:$PATH"
从~/.profile文件中代码不难发现,/.profile文件只在用户登录的时候读取一次,而/.bashrc会在每次运行Shell脚本的时候读取一次。
一些小技巧:
可以自定义一个环境变量文件,比如在某个项目下定义uusama.profile,在这个文件中使用export定义一系列变量,然后在~/.profile文件后面加上:sourc uusama.profile,这样你每次登陆都可以在Shell脚本中使用自己定义的一系列变量。
也可以使用alias命令定义一些命令的别名,比如alias rm="rm -i"(双引号必须),并把这个代码加入到~/.profile中,这样你每次使用rm命令的时候,都相当于使用rm -i命令,非常方便。