关于ansible远程执行的环境变量问题(login shell & nonlogin shelll)
来源:互联网 发布:互联网之子 知乎 编辑:程序博客网 时间:2024/06/14 00:53
- 问题
- 排查过程
- 原因
- login shell 和 non-login shell
- 验证
- login shell
- 按照环境变量的加载顺序
- 运行结果
- non-login shell
- 按照环境变量的加载顺序
- 运行结果
- login shell下启动bash子进程
- 按照环境变量的加载顺序
- 运行结果
- login shell
- 结论
问题
ansible调用playbook远程mvn执行打包时发现执行出错,找不到JAVA_HOME
。
我们的exporter JAVA_HOME=/usr/java/jdk1.8.0
写在/etc/profile
中,登录时可以正常执行打包并打印JAVA_HOME
。
排查过程
- 在playbook中执行
echo $JAVA_HOME > /tmp/test.log
,为空 - 在playbook中添加
echo $PATH > /tmp/test.log
,同时在远端服务器登录执行echo $PATH > /tmp/test.log
,结果不同,ansible执行的要少很多路径 - 在
~/.bash_profile
中添加环境变量,与/etc/profile
结果一致 - 考虑ansible执行的环境变量与登录时使用的环境变量不同,所以将
JAVA_HOME
写在/etc/bashrc
中,再次测试echo $JAVA_HOME > /tmp/test.log
,正常打印 - 至此,确定ansible执行过程中并未调用
/etc/profile和~/.bash_profile
原因
login shell 和 non-login shell
查阅相关文档,以及咨询大佬后,得出如下结果。
* 我们登录执行的是login shell,会加载/etc/profile,~/.bash_profile
* ansible这类ssh远程执行是non-login shell,不会加载etc/profile,~/.bash_profile,而是加载etc/bashrc和~/.bashrc
首先了解一下login shell 与 non-login shell
《鸟哥的Linux私房菜基础学习篇》里这样描述/etc/profile及/etc/bashrc的区别:
* login shell:取得bash时需要完整的登入流程的,就称为login shell。举例来说,你要由tty1~tty6登入,需要输入用户的账号和密码,此时取得的bash就称为『login shell』啰;
* non-login shell:取得bash接口的方法不需要重复登入的举动,举例来说,(1)你以Xwindow登入Linux后,再以X的图形化接口启动终端机,此时那个终端接口并没有需要再次的输入账号和密码,那个bash的环境就称为non-login shell了。(2)你在原本的bash环境下再次下达bash这个命令,同样的也没有输入账号密码,那第二个bash (子程序)也是non-login shell 。
我们查看~/.bash_profile,发现里面有这样一段内容:
if [ -f ~/.bashrc ]; then . ~/.bashrcfi
当~/.bashrc存在时,login shell 会引入~/.bashrc的环境变量
我们再看~/.bashrc,发现一段类似的内容:
if [ -f /etc/bashrc ]; then . /etc/bashrcfi
当/etc/bashrc存在时,login shell会引入/etc/bashrc内的环境变量
也就是说:
* login shell加载环境变量的顺序是:① /etc/profile ② ~/.bash_profile ③ ~/.bashrc ④ /etc/bashrc
* 而non-login shell加载环境变量的顺序是: ① ~/.bashrc ② /etc/bashrc
验证
我们通过在~/.bash_profile和~/.bashrc中引用不同的变量计算来验证上述问题
* 在~/.bash_profile中引入变量AAA=$((AAA+1))
注意:引入的变量一定要置于引入~/.bashrc之前,否则会出现运算时AAA还未赋值的情况!!!
export AAA=$((AAA+1))
- 在~/.bashrc中引入变量AAA=$((AAA+10))
export AAA=$((AAA+10))
login shell
按照环境变量的加载顺序:
- ~/.bash_profile
AAA=$((AAA+1)),AAA为空,AAA=$((AAA+1))=1
- ~/.bashrc
AAA=$((AAA+10)),AAA=1,AAA=$((AAA+10))=11
运行结果
[root@ ~]# echo $AAA11
验证通过
non-login shell
采用ssh远程执行来验证
按照环境变量的加载顺序:
- ~/.bashrc
AAA=$((AAA+10)),AAA为空,AAA=$((AAA+10))=10
运行结果
[root@ ~]# ssh root@1.1.1.2 'echo $AAA'root@1.1.1.2's password: 10
验证通过
login shell下启动bash子进程
bash子进程是一个non-login shell,但是它会继承父进程中的环境变量
按照环境变量的加载顺序:
- 父进程,引入~/.bash_profile
AAA=$((AAA+1)),AAA为空,AAA=$((AAA+1))=1
- 父进程,引入~/.bashrc
AAA=$((AAA+10)),AAA=1,AAA=$((AAA+10))=11
- 子进程,继承父进程环境变量,引入~/.bashrc
AAA=$((AAA+10)),AAA=11,AAA=$((AAA+10))=21
运行结果
# 父进程[root@ ~]# echo $AAA11# bash子进程,继承AAA=11[root@ ~]# bash[root@ ~]# echo $AAA21# 子进程的子进程,继承AAA=21[root@ ~]# bash[root@ ~]# echo $AAA31
验证通过
结论
- ansible这类远程执行的non-login shell 并不会加载/etc/profile和~/.bash_profile下的环境变量,只是加载~/.bashrc和/etc/bashrc
- 如果需要在ansible中执行需要特定环境变量的命令,可以在执行前source一下~/.bash_profile, 或者将环境变量写在~/.bashrc 。
- 关于ansible远程执行的环境变量问题(login shell & nonlogin shelll)
- ssh连接远程主机执行脚本的环境变量问题
- ssh连接远程主机执行脚本的环境变量问题
- ssh连接远程主机执行脚本的环境变量问题
- ssh连接远程主机执行脚本的环境变量问题
- ssh连接远程主机执行脚本的环境变量问题
- 执行远程服务器上的脚本失败?(环境变量引起的问题)
- login shell和non-login shell环境配置、 环境变量的设置、查看
- shell脚本的执行环境变量
- 关于linux Shell crontab 执行当前环境变量
- jenkins执行shell读不到环境变量问题
- linux中关于login shell和non-login shell的介绍
- shell的执行问题
- 环境配置文件 ① /etc/profile、② ~/.bash_profile、③ ~/.bashrc、④ /etc/bashrc 作用与执行顺序,以及与login/nonlogin关系
- 关于php执行shell脚本需要注意的问题
- 关于ansible的优化
- linux的Shelll 编程
- 关于SSH远程登录和远程连续执行代码的一些问题
- linux内核USB无线网卡、USB声卡支持
- matlab simulink 仿真时出现如下错误怎么办
- Sass
- 输出一个花样桃心
- spring-cloud中eureka进行服务治理
- 关于ansible远程执行的环境变量问题(login shell & nonlogin shelll)
- git
- golang基础-模板if判断、传(map_arr切片)数据渲染浏览器
- 素数对
- 最长公共子串
- flex自适应邮箱布局
- 安装完PyUserInput后,相关模块导入异常处理
- yum工具用法
- jy-大佬作业笔记