浅谈linux 环境变量

今日在复习docker知识并且重新构建dockerfile qq机器人的过程中 etc/profile 加入环境变量更新shell时总会失效。

本文对于linux环境变量浅谈一下各种情况。如有疏漏错误,还请各位师傅指正。

本文解决的问题

在dockerfile中将环境变量写入 /etc/profile 构建容器后 每次shell连接仍需手动source

shell登陆模式

在搜索一番过后 很多文章都说 etc/profile 为全局变量 建立shell连接会自动执行

但是docker交互重新连接后环境变量 还需手动 source etc/profile

最后发现核心点在于shell的登陆方式

login/non-login shell 对环境的影响

login shell:此种方式登录时,shell 会重新读取/etc/profile和/.bash_profile来应用新的环境变量。 non-login shell:此时 shell 不会读取 /etc/profile 和 `/.bash_profile,而是读取 ~/.bashrc` 来应用新的环境变量。

Login shell在何处

使用ssh登录云服务器后,使用logout命令可以退出登录。但是使用docker exec -it xxx bash进入容器后,却不能使用logout退出,只能使用exit

1
2
3
root@hecs-235922:~/dockefilestudy# docker exec -it b5a bash
root@b5a7034267c4:/# logout
bash: logout: not login shell: use `exit'

sudo命令有一个参数-i,用于运行一个login shell

1
2
3
4
$ sudo --help
...
-i, --login run login shell as the target user; a command may also be specified
...

su命令也有类似的参数:

1
2
3
4
$ su --help
...
-, -l, --login make the shell a login shell
...

login shell 的定义

1
2
A login shell is one whose first character of argument zero is a -, or one started with the –login option.
深入简出 一个shell是login shell,要么【条件1】,要么【条件2】。
第一个条件

先来看看条件1: first character of argument zero is a -,即一个shell的argument zero的第一个字符是个连字符”-“。在这里,argument zero其实指的是$0

$0是shell的一个参数,这个参数保存的是bash脚本的名称,bash初始化的时候会设置$0这个变量。与之类似的还有$$$*$#等等。

在bash中打印一下:

1
2
root@hecs-235922:~/dockefilestudy# echo $0
-bash

可以看到,打印出来脚本名称是-bash,第一个字符是”-“,说明这个是一个login shell。

使用ps命令查看进程,也可以看到bash的进程名称为-bash:

1
root     15517  0.0  0.1   8048  4540 pts/0    Ss   12:57   0:00 -bash

如果打印出来第一个字符不是“-”, 例如:

1
2
$ echo $0
bash

也并不能确认此登陆一定不是login shell 还需要考虑第二个条件。

第二个条件

回到定义or one started with the –login option. 登陆的时候需要有 -login参数

Docker exec 交互一下:

1
2
3
root@hecs-235922:~/dockefilestudy# docker exec -it b5a bash
root@b5a7034267c4:/# logout
bash: logout: not login shell: use `exit'

附带 –login参数:

1
2
root@hecs-235922:~/dockefilestudy# docker exec -it b5a bash --login
root@b5a7034267c4:/# logout

由上文可以看到 在进行交互的时候带上 –login 参数 便进行login shell连接

回到文章开头 便可清晰了解为何

关于环境变量配置

方法一 export PATH
1
2
3
export PATH=/home/xxx:PATH
# 或者把PATH放在前面
export PATH=PATH:/home/xxx

生效时间:立即生效 生效期限:当前终端有效,窗口关闭后无效 生效范围:仅对当前用户有效 配置的环境变量中不要忘了加上原来的配置,即$PATH部分,避免覆盖原来配置

方法二 修改**~/.bashrc | ~/.bash_profile**

生效时间:使用相同的用户打开新的终端时生效,或者手动source ~/.bashrc生效 生效期限:永久有效 生效范围:仅对当前用户有效 如果有后续的环境变量加载文件覆盖了PATH定义,则可能不生效

方法三 修改 /etc/bashrc
1
2
# 在最后一行加上
export PATH=PATH:/home/xxx

生效时间:新开终端生效,或者手动source /etc/bashrc生效 生效期限:永久有效 生效范围:对所有用户有效

方法四 修改**/etc/profile**

生效时间:新开终端生效,或者手动source /etc/profile生效 生效期限:永久有效 生效范围:对所有用户有效