当前位置: 首页 > news >正文

关于ansible远程执行的环境变量问题(login shell nonlogin shelll)

为什么80%的码农都做不了架构师?>>>   hot3.png

问题

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
        . ~/.bashrc
fi
  • 1
  • 2
  • 3

当~/.bashrc存在时,login shell 会引入~/.bashrc的环境变量

我们再看~/.bashrc,发现一段类似的内容:

if [ -f /etc/bashrc ]; then
        . /etc/bashrc
fi
  • 1
  • 2
  • 3

当/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))
  • 1
  • 在~/.bashrc中引入变量AAA=$((AAA+10))
export AAA=$((AAA+10))
  • 1

login shell

按照环境变量的加载顺序:

  1. ~/.bash_profile 
    AAA=$((AAA+1)),AAA为空,AAA=$((AAA+1))=1
  2. ~/.bashrc 
    AAA=$((AAA+10)),AAA=1,AAA=$((AAA+10))=11

运行结果

[root@ ~]# echo $AAA
11
  • 1
  • 2

验证通过

non-login shell

采用ssh远程执行来验证

按照环境变量的加载顺序:

  1. ~/.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
  • 1
  • 2
  • 3

验证通过

login shell下启动bash子进程

bash子进程是一个non-login shell,但是它会继承父进程中的环境变量

按照环境变量的加载顺序:

  1. 父进程,引入~/.bash_profile 
    AAA=$((AAA+1)),AAA为空,AAA=$((AAA+1))=1
  2. 父进程,引入~/.bashrc 
    AAA=$((AAA+10)),AAA=1,AAA=$((AAA+10))=11
  3. 子进程,继承父进程环境变量,引入~/.bashrc 
    AAA=$((AAA+10)),AAA=11,AAA=$((AAA+10))=21

运行结果

# 父进程
[root@ ~]# echo $AAA
11
# bash子进程,继承AAA=11
[root@ ~]# bash
[root@ ~]# echo $AAA
21
# 子进程的子进程,继承AAA=21
[root@ ~]# bash
[root@ ~]# echo $AAA
31
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

验证通过

结论

  • ansible这类远程执行的non-login shell 并不会加载/etc/profile和~/.bash_profile下的环境变量,只是加载~/.bashrc和/etc/bashrc
  • 如果需要在ansible中执行需要特定环境变量的命令,可以在执行前source一下~/.bash_profile, 或者将环境变量写在~/.bashrc 。

转载于:https://my.oschina.net/yygh/blog/1822406

相关文章:

  • Effective C++ 学习笔记[1]
  • Spring Boot 2.0 with Spring 5 Kotlin support and Spring WebFlux functional
  • mysql表分区案例
  • C# :WinForm TextBox猜想输入和历史记录输入
  • 并发服务器:Redis案例研究分析
  • POJ 3041 Asteroids (最小点覆盖集)
  • 不通过调用__Init__来创建实例
  • 算法学习--动手
  • 10-padding(内边距)
  • linux中grep和egrep的用法
  • hashlib模块学习:hmac
  • 开发基于以太坊智能合约的DApp
  • vue-cli脚手架一些插件安装elementui和axios
  • MD5加密解密
  • MS SQL 需要定期清理日志文件
  • 07.Android之多媒体问题
  • Android框架之Volley
  • Git同步原始仓库到Fork仓库中
  • JAVA SE 6 GC调优笔记
  • JAVA之继承和多态
  • MQ框架的比较
  • mysql 5.6 原生Online DDL解析
  • MySQL用户中的%到底包不包括localhost?
  • oldjun 检测网站的经验
  • vue 个人积累(使用工具,组件)
  • vue从创建到完整的饿了么(18)购物车详细信息的展示与删除
  • Yii源码解读-服务定位器(Service Locator)
  • 服务器从安装到部署全过程(二)
  • 构建工具 - 收藏集 - 掘金
  • 我感觉这是史上最牛的防sql注入方法类
  • d²y/dx²; 偏导数问题 请问f1 f2是什么意思
  • PostgreSQL 快速给指定表每个字段创建索引 - 1
  • #{} 和 ${}区别
  • #{}和${}的区别?
  • #define与typedef区别
  • #ifdef 的技巧用法
  • #pragma data_seg 共享数据区(转)
  • #图像处理
  • #微信小程序:微信小程序常见的配置传旨
  • (1)(1.13) SiK无线电高级配置(六)
  • (2)MFC+openGL单文档框架glFrame
  • (C++20) consteval立即函数
  • (HAL库版)freeRTOS移植STMF103
  • (Mac上)使用Python进行matplotlib 画图时,中文显示不出来
  • (附源码)计算机毕业设计ssm本地美食推荐平台
  • (六)vue-router+UI组件库
  • (十八)三元表达式和列表解析
  • (转)拼包函数及网络封包的异常处理(含代码)
  • ******IT公司面试题汇总+优秀技术博客汇总
  • ***详解账号泄露:全球约1亿用户已泄露
  • .[hudsonL@cock.li].mkp勒索加密数据库完美恢复---惜分飞
  • .desktop 桌面快捷_Linux桌面环境那么多,这几款优秀的任你选
  • .Net CF下精确的计时器
  • .NET Framework 和 .NET Core 在默认情况下垃圾回收(GC)机制的不同(局部变量部分)
  • .net framework4与其client profile版本的区别