今日在复习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来应用新的环境变量。 /.bash_profilenon-login shell
:此时 shell
不会读取 /etc/profile
和 `,而是读取
~/.bashrc` 来应用新的环境变量。
Login shell在何处
使用ssh登录云服务器后,使用logout
命令可以退出登录。但是使用docker exec -it xxx bash
进入容器后,却不能使用logout
退出,只能使用exit
:
1 | root@hecs-235922:~/dockefilestudy# docker exec -it b5a bash |
sudo
命令有一个参数-i
,用于运行一个login shell
:
1 | $ sudo --help |
su
命令也有类似的参数:
1 | $ su --help |
login shell 的定义
1 | A login shell is one whose first character of argument zero is a -, or one started with the –login option. |
第一个条件
先来看看条件1: first character of argument zero is a -
,即一个shell的argument zero
的第一个字符是个连字符”-“。在这里,argument zero
其实指的是$0
。
$0
是shell的一个参数,这个参数保存的是bash脚本的名称,bash初始化的时候会设置$0
这个变量。与之类似的还有$$
、$*
、$#
等等。
在bash中打印一下:
1 | root@hecs-235922:~/dockefilestudy# echo $0 |
可以看到,打印出来脚本名称是-bash
,第一个字符是”-“,说明这个是一个login shell。
使用ps
命令查看进程,也可以看到bash的进程名称为-bash
:
1 | root 15517 0.0 0.1 8048 4540 pts/0 Ss 12:57 0:00 -bash |
如果打印出来第一个字符不是“-”, 例如:
1 | $ echo $0 |
也并不能确认此登陆一定不是login shell 还需要考虑第二个条件。
第二个条件
回到定义or one started with the –login option.
登陆的时候需要有 -login参数
Docker exec 交互一下:
1 | root@hecs-235922:~/dockefilestudy# docker exec -it b5a bash |
附带 –login参数:
1 | root@hecs-235922:~/dockefilestudy# docker exec -it b5a bash --login |
由上文可以看到 在进行交互的时候带上 –login 参数 便进行login shell连接
回到文章开头 便可清晰了解为何
关于环境变量配置
方法一 export PATH
1 | export PATH=/home/xxx:PATH |
生效时间:立即生效 生效期限:当前终端有效,窗口关闭后无效 生效范围:仅对当前用户有效 配置的环境变量中不要忘了加上原来的配置,即$PATH部分,避免覆盖原来配置
方法二 修改**~/.bashrc | ~/.bash_profile**
生效时间:使用相同的用户打开新的终端时生效,或者手动source ~/.bashrc生效 生效期限:永久有效 生效范围:仅对当前用户有效 如果有后续的环境变量加载文件覆盖了PATH定义,则可能不生效
方法三 修改 /etc/bashrc
1 | # 在最后一行加上 |
生效时间:新开终端生效,或者手动source /etc/bashrc生效 生效期限:永久有效 生效范围:对所有用户有效
方法四 修改**/etc/profile**
生效时间:新开终端生效,或者手动source /etc/profile生效 生效期限:永久有效 生效范围:对所有用户有效