shell脚本切换用户 ansible 远程执行shell时的变量问题
一 问题现象
最近在研究 基于ansible 开发自动化部署工具安装部署各种软件,以便提高部署效率。其中一个产品底层含有7个组件,软件初始化都是通过人工执行shell脚本,其中脚本中还含有 启动 java进程。通过ansible部署的时候报错,找不到特定的环境变量,程序无法正常启动。
二 原因分析2.1 问题验证
通过对比ansible 和在目标机器上分别执行 env 命令,我们可以发现通过 ansible 执行的缺少非常多变量。
通过ansible执行env命令的结果
在本机执行 env 命令的结果
2.2 linux 的 login shell 和 non-longin shell
login shell: 登陆 Linux 系统时需要完整的输入用户名密码的过程,此时获取的bash环境则是 login shell
non-login shell : 不需要重复输入用户名密码的登陆即可获取bash。比如在已经登陆情况下,执行 su 用户或者 bash 切换环境就是 non-login shell 。
我们可以通过如下的例子直观感受两者的差异:
### 第一次通过用户名登陆linux系统。
-bash-4.2# id
uid=0(root) gid=0(root) 组=0(root)
-bash-4.2# su polardb
bash-4.2$ # non-login shell
bash-4.2$ exit
exit
-bash-4.2# su - polardb
上一次登录:三 8月 11 20:52:03 CST 2021pts/0 上
-bash-4.2$ login shell 环境
-bash-4.2$ bash ##执行bash命令切换为 non-login shell
bash-4.2$
重点来了,两种shell 情况下加载系统环境变量的路径是不一样的,变量加载顺序:
login shell 加载环境变量的顺序是:
/etc/profile -> ~/.bash_profile -> ~/.bashrc -> /etc/bashrc
而non-login shell加载环境变量的顺序是:
~/.bashrc -> /etc/bashrc
如果我们将环境变量写入到 ~/.bash_profile 或者 /etc/profileshell脚本切换用户,那么只有用户以 login shell 方式登陆系统才会获取到系统变量或者执行命令之前操作 source /etc/profile
而以 non-login 方式进入 bash ,只能获取到 ~/.bashrc 和 /etc/bashrc 文件中的系统变量。ansible是以 non-login 方式运行的,故读取不到 /etc/profile 文件中的变量。所以需要将环境变量配置在 /etc/bashrc 中才能成功。
三 解决方法
其实第二部分已经分析了shell脚本切换用户,通过将命令写入到 /etc/bashrc 或者在远程机器执行的脚本里面加上 source /etc/profile 命令辅助论坛,这样脚本就能获取到想要的系统变量了。
四 小结
对于通用的软件而言还是建议将系统变量写入到 /etc/bashrc 文件中。longin-shell 和non-login shell 都可以读取到系统变量,提升可运维性。
来源:【九爱网址导航www.fuzhukm.com】 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!