Linux 环境变量配置(翻新)

Linux 是多用户操作系统,每个用户登陆后都有属于自己的环境,定义着自己专有的变量值。同时 Linux 是基于文件,和 Windows 的注册表很不相同。

本文是基于 Ubuntu 所写,其它 Linux 系统设置其本雷同。2018/12/18 升级内容到 18.04 版本。

举例来说,在终端下,你输入一个命令,会出现 Command not found , 但系统中已经安装过该程序,只是不在标准位置,此时你只能通过全路径的方式来执行 /usr/local/app/bin/run,但每次输入很是繁琐,这时就可以通过添加该目录到系统环境变量 PATH 中来实现执行文件的查找。

http://imcn.me/wp-content/uploads/2010/04/ubuntu-ad1.jpg


# 变量认识及使用

> 显示当前所有的变量值

环境变量是在终端(Shell)中被使用,也可以通过 Shell 来对其进行操作,所有变量值均使用大写。

打印所有变量值:

1
2
$ env
$ export

打印系统 PATH 中的所有路径:

1
$ echo $PATH

打印 USER 变量值:

1
$ echo $USER

也可通过 set 来显示本地定义的变量集

> 设置新的变量

在 Shell 中,可以通过 export 命令来设置新的变量,如下,创建新的变量 MYVAR

1
2
$ export MYVAR=”lanvige.com”
$ echo $MYVAR

> 使用 readonly 命令创建只读变量

1
2
$ export MYVAR=”lanvige.com”
$ readonly MYVAR

> 清除环境变量

在 Shell 中可以使用 unset 命令来清除变量值

1
$ unset MYVAR

> 常用到的环境变量

1
2
3
4
5
PATH          决定了shell将到哪些目录中寻找命令或程序
HOME       当前用户主目录
LOGNAME/USER   当前用户的登录名
HOSTNAME     指主机的名称
SHELL       前用户Shell类型

# 环境变量模式

> interactive & non-interactive | 交互式和非交互式

其实 BASH 有两种工作模式,就是:交互式和非交互式

交互式模式:就是在终端上执行,shell 等待你的输入,并且立即执行你提交的命令。这种模式被称作交互式是因为shell与用户进行交互。当你退出后,shell也终止了。

非交互模式:以 Shell Script(非交互) 方式执行。在这种模式下,Shell 不与你进行交互,而是读取存放在文件中的命令,执行它们。当它读到文件的结尾EOF,Shell 也就终止了。

区别:读取的配置文件不同,交互式读取 ~/.bashrc 文件;非交互式读取的是环境变量 BASH_ENV(通常情况下)所指定的配置文件。

> login shell & non-login shells | 登陆 Shell 与非登陆 Shell

用文本方式登录之后,得到的就是一个 login shell,如果在这个 shell 里执行一下 bash 命令,就得到一个 non-login shell

对于用户来说,login shellnon-login shell 的主要区别是:启动 shell 时所执行的 startup 文件不同。

  • 登陆 shell 执行文件为:/etc/profile~/.profile~/.bashrc
  • 非登陆 shell 执行的文件仅为:~/.bashrc,如果在运行之前,修改 profile 文件的话对它不起作用。。

~/.profile: 是 interactive & login shell 方式进入 bash 运行的
~/.bashrcinteractive & non-login 方式进入 bash 运行的

通常二者设置大致相同。在系统中前者会调用后者。


# 配置环境变量文件

> 认识环境变量文件

在 Ubuntu 18.04 中有如下文件可以设置环境变量,对应着系统级别[所有用户]和用户级别[个人用户],分别放在 /etc/~/ 下。同时这几个文件有着明确执行顺序。

- /etc/profile || /etc/bash.bashrc

系统登录时,定制用户环境时使用的第一个文件,为系统的所有用户设置环境变量,当用户第一次登录时,该文件被执行。

profile 中调用了 bash.bashrc。

- ~/.profile

交互式登录 shell - interactive & login shells,在 login 方式登陆时,该文件被执行,且仅执行一次。

该文件会在每次bash shell打开时被执行,在当前Shell中添加环境变量。

- ~/.bashrc

交互式非登录 shell - interactive non-login shells

当登录时以及每次打开新的 shell 时,该文件被读取。(non-login 形式执行时,读取此文件。若是以 login 形式执行,则不会读取此文件)
某用户专有设定文档,可以设定路径,命令别名,每次 shell script 的执行都会使用它一次

- ~/.bash_logout

当每次退出系统(退出bash shell)时,执行该文件。

> 各种模式的读取顺序

  • 图形模式登录:/etc/profile > ~/.profile
  • 图形模式登录后,打开终端时:/etc/bash > bashrc > ~/.bashrc
  • 文本模式登录时,顺序读取:/etc/bash > /etc/bashrc > /etc/profile > ~/.bash_profile
  • 从其它用户 su 到该用户,则分两种情况:
    • 如果带-l参数(或-参数,–login参数),如:su -l username,则bash是lonin的,它将顺序读取以下配置文件:/etc/bash > bashrc > /etc/profile > ~/.bash_profile
    • 如果没有带 -l 参数,则 bash 是 non-login 的,它将顺序读取:/etc/bash > /etc/bashrc > ~/.bashrc
  • 注销时,或退出su登录的用户,如果是longin方式,那么bash会读取:~/.bash_logout
  • 执行自定义的shell文件时,若使用bash -l a.sh的方式,则bash会读取行:/etc/profile > ~/.bash_profile,若使用其它方式,如:bash a.sh./a.shsh a.sh(这个不属于bash shell),则不会读取上面的任何文件。

# 实例:设置永久环境变量

刚已经演示如何添加环境变量,但通过 export 方式所添加变量值的生命周期仅为当前 shell,重新打开新的 shell 时,该变量会丢失,如何设置一个永久的变量值,可以根据你的需求将变量值添加到上述5个文件中的其中一个来实现。

如果我们想在变量中加入新的path,则可以如下:

1
$ vim ./bashrc

添加如下行在未尾,这里需考虑 PATH 查找优先级,如一个命令在不同的 PATH 中出现,会使用最前定义的 PATH 值,多个 PATH 间用:隔开。

1
export PATH="PATH=$PATH:<PATH 1>:<PATH 2>"

使其生效

刚有提到,当改变配置文件时,重启shell才能使其生效,但通过source命令也能达到同样的效果,如果修改的是.bashrc文件,则输入。

1
$ source ~/.bashrc

FAQ::


> rc 全称

配置文件 .bashrcrc 的含义是 resource configuration

> ISSUE: 执行脚本时的问题:

在 Unicorn&Nginx 的 Init 脚本配置中,需要使用 rbenv 中的shims,但 rbenv 的环境变量被配置在了~/.bashrc中,如果直接执行像unicorn来启动服务是没有问题的,但在脚本文件中调用 unicorn 就不行。会有 Command Not Found 的问题,在 sh 文件中配置 PATH 也不会生效。最后将rbenv的环境变量配置移动到 ~/.profile 中问题就解决了。


# REF::