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 | env |
打印系统 PATH 中的所有路径:
1 | echo $PATH |
打印 USER 变量值:
1 | echo $USER |
也可通过 set 来显示本地定义的变量集
> 设置新的变量
在 Shell 中,可以通过 export
命令来设置新的变量,如下,创建新的变量 MYVAR
:
1 | $ export MYVAR=”lanvige.com” |
> 使用 readonly
命令创建只读变量
1 | $ export MYVAR=”lanvige.com” |
> 清除环境变量
在 Shell 中可以使用 unset
命令来清除变量值
1 | unset MYVAR |
> 常用到的环境变量
1 | PATH 决定了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 shell
和 non-login shell
的主要区别是:启动 shell 时所执行的 startup 文件不同。
- 登陆 shell 执行文件为:
/etc/profile
、~/.profile
、~/.bashrc
- 非登陆 shell 执行的文件仅为:
~/.bashrc
,如果在运行之前,修改profile
文件的话对它不起作用。。
~/.profile
: 是 interactive & login shell
方式进入 bash 运行的~/.bashrc
是 interactive & 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.sh
,sh 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 全称
配置文件 .bashrc
中 rc
的含义是 resource configuration
。
> ISSUE: 执行脚本时的问题:
在 Unicorn&Nginx 的 Init 脚本配置中,需要使用 rbenv 中的shims,但 rbenv 的环境变量被配置在了~/.bashrc
中,如果直接执行像unicorn来启动服务是没有问题的,但在脚本文件中调用 unicorn 就不行。会有 Command Not Found
的问题,在 sh 文件中配置 PATH 也不会生效。最后将rbenv的环境变量配置移动到 ~/.profile
中问题就解决了。