Linux环境变量

什么是环境变量

bash shell用环境变量的特性来存储有关shell会话和工作环境的信息,这种特性允许在内存中存储数据,以便程序或shell中运行的脚本能轻松的访问它们。在bash shell中,环境变量分为两类:

  • 全局变量
  • 局部变量

全局环境变量

全局环境变量对于shell会话和所有生成的子shell都是可见的。局部变量则只对创建它们的 shell可见。Linux系统在开始bash会话时就设置了一些全局环境变量。系统环境变量基本上都是使用全大写字母,以区别于普通用户的环境变量。 

查看全部全局变量,可以使用env或printenv命令:

[root@bogon ~]# printenv > enironment_v1
[root@bogon ~]# env > enironment_v2
[root@bogon ~]# diff enironment_v1 enironment_v2
46c46
< _=/usr/bin/printenv
---
> _=/usr/bin/env

查看个别变量的值,可以使用printenv,但不能使用env:

[root@bogon ~]# printenv HOME
/root

  [root@bogon ~]# env HOME 
  env: HOME: No such file or directory

或者使用echo显示变量的值:

[root@bogon ~]# echo $HOME
/root

局部环境变量

局部环境变量只能在定义它们的进程中可见。Linux系统也默认定义了标准的局部环境变量。不过也可以定义自己的局部变量,这些变量被称为用户定义局部变量。 

在Linux系统并没有一个只显示局部环境变量的命令,使用set命令会显示为某个特定进程设置的所有环境变量,包括局部变量、全局变量 以及用户定义变量:

[root@bogon ~]# set 
ABRT_DEBUG_LOG=/dev/null
BASH=/usr/bin/bash
BASHOPTS=checkwinsize:cmdhist:expand_aliases:extglob:extquote:force_fignore:histappend:interactive_comme
nts:progcomp:promptvars:sourcepath
......

设置用户定义变量

设置局部用户定义变量

一旦启动了bash shell(或者执行一个shell脚本),就能创建在这个shell进程内可见的局部变量。可以通过等号给环境变量赋值,值可以是数值或字符串。 

[root@bogon ~]# echo $my_variable

[root@bogon ~]# my_variable=Hello
[root@bogon ~]# echo $my_variable
Hello

注意:所有的环境变量名均使用大写字母,这是bash shell的标准惯例。如果是自己创建的局部变量或是shell脚本,应当使用小写字母。

设置全局环境变量

在设定全局环境变量的进程所创建的子进程中,该变量都是可见的。创建全局环境变量的方法是先创建一个局部环境变量,然后再把它导出到全局环境中(通过export命令来完成,变量名前面不需要加$)。

[root@bogon ~]# my_variable=Global
[root@bogon ~]# export my_variable
[root@bogon ~]# echo $my_variable
Global
[root@bogon ~]# bash 
[root@bogon ~]# echo $my_variable
Global

在子shell中修改环境变量的值不会影响父shell,子shell甚至无法使用export命令改变父shell中全局变量的值。

删除环境变量

使用unset命令可以删除环境变量(在unset命令中引用环境变量时,不要使用$):

[root@bogon ~]# unset $my_variable  
[root@bogon ~]# echo $my_variable 
Global
[root@bogon ~]# unset my_variable
[root@bogon ~]# echo $my_variable 

如果要用到变量,使用$;如果要操作变量,不使用$。(一个例外就是printenv显示环境变量)

与修改变量一样,在子shell中删除全局变量无法将效果反映到父shell中。

设置PATH环境变量

当你在shell命令行界面中输入一个外部命令时,shell必须搜索系统来找到对应的程序。PATH环境变量定义了用于进行命令和程序查找的目录。

[root@bogon ~]# echo $PATH
/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/root/bin:/usr/local/python37/bin

将新的搜索目录添加到现有的PATH环境变量中,无需从头定义。PATH中各个目录之间使用冒号分隔,只需引用原来的PATH值,然后再给这个字符串添加新目录即可:

[root@bogon ~]# echo $PATH
/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/root/bin:/usr/local/python37/bin
[root@bogon ~]# PATH=$PATH:/home/letty/scripts
[root@bogon ~]# echo $PATH
/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/root/bin:/usr/local/python37/bin:/home/letty/scripts

定位系统环境变量

如何让环境变量的作用持久化?在登入Linux系统启动一个bash shell时,默认情况下bash会在几个文件中查找命令,这些文件叫作启动文件或环境文件。bash检查的启动文件取决于启动bash shell的方式,启动bash shell有3种方式: 

  • 作为登陆时默认登陆shell
  • 作为非登陆shell的交互式shell
  • 作为运行脚本的非交互shell

登录shell

登录Linux系统时,bash shell会作为登录shell启动。登录shell会从5个不同的启动文件里 读取命令: 

  • /etc/profile
  • $HOME/.bash_profile
  • $HOME/.bashrc
  • $HOME/.bash_login
  • $HOME/.profile

1. /etc/profile文件

/etc/profile文件是bash shell默认的的主启动文件,只要你登录Linux系统,bash就会执行 /etc/profile启动文件中的命令。

2. $HOME目录下的启动文件

shell会按照按照下列顺序,运行第一个被找到的文件,余下的则被忽略:

  • $HOME/.bash_profile
  • $HOME/.bash_login
  • $HOME/.profile

注意:该列表中并没有$HOME/.bashrc文件,是因为该文件通常通过其他文件运行的。

交互式shell进程

如果bash shell不是登录系统时启动的(比如是在命令行提示符下敲入bash时启动),那么启动的shell叫作交互式shell。交互式shell不会像登录shell一样运行,但它依然提供了命令行 提示符来输入命令。 如果bash是作为交互式shell启动的,它就不会访问/etc/profile文件,只会检查用户HOME目录中的.bashrc文件。 

.bashrc文件有两个作用:

  • 查看/etc目录下通用的bashrc文件
  • 为用户提供一个定制自己的命令别名和私有脚本函数的地方

非交互式shell

当shell启动一个非交互式shell进程时,它会检查BASH_ENV环境变量来查看要执行的启动文件。如果有指定的文件,shell会执行该文件里的命令,这通常包括shell脚本变量设置。 

如果BASH_ENV变量没有设置,有些 shell脚本可以通过启动一个子shell来执行的,子shell可以继承父shell导出过的变量,由父shell设置但并未导出的变量都是局部变量,子shell无法继承局部变量。 

对于那些不启动子shell的脚本,变量已经存在于当前shell中了,所以就算没有设置 BASH_ENV,也可以使用当前shell的局部变量和全局变量。

环境变量持久化

全局环境变量更倾向于将新的或修改过的变量设置放在/etc/profile文件中,但如果升级了所用的发行版, 该文件也会跟着更新,所有定制过的变量设置就都没有了。

最好是在/etc/profile.d目录中创建一个以.sh结尾的文件,把所有新的或修改过的全局环境变 量设置放在这个文件中。

在大多数发行版中,存储个人用户永久性bash shell变量的地方是$HOME/.bashrc文件

 

参考技术书籍:《Linux命令行与脚本编程大全》

Linux环境变量

上一篇:Leetcode 5. 最长回文子串


下一篇:ubuntu 用 gedit编辑code出现的 中文乱码问题