ansible设置环境变量不生效的问题:ansible etcd -m shell -a "export ETCDCTL_API=3"
需求
搭建etcd集群,设置版本,发现ansible写不了环境变量,所以查了一下。
结论
ansible这类远程执行的non-login shell 并不会加载/etc/profile和/.bash_profile下的环境变量,只是加载/.bashrc和/etc/bashrc
如果需要在ansible中执行需要特定环境变量的命令,可以在执行前source一下~/.bash_profile, 或者将环境变量写在~/.bashrc 。
————————————————
版权声明:本文为CSDN博主「huangwjwork」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u010871982/article/details/78525367
问题
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,结果不同,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
. ~/.bashrc
fi
当~/.bashrc存在时,login shell 会引入~/.bashrc的环境变量
我们再看~/.bashrc,发现一段类似的内容:
if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi
当/etc/bashrc存在时,login shell会引入/etc/bashrc内的环境变量
也就是说:
- login shell加载环境变量的顺序是:
① /etc/profile ② ~/.bash_profile ③ ~/.bashrc ④ /etc/bashrc
- 而non-login shell加载环境变量的顺序是:
① ~/.bashrc ② /etc/bashrc
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构