背景

项目中使用到了pm2,用于管理微服务的启停,我在相关机器上安装好了pm2,然后使用ansible进行批量启动服务。在使用ansible的shell模块执行远程命令时候却报了错:/bin/sh: pm2 :command not found,如下图

问题定位

1. 在被执行机器上查看pm2命令,看看是不是没有添加到环境变量(PATH)里。

登陆到这台机器上,执行:which pm2

可以看到pm2已安装到机器上了。

再看看是否已添加到环境变量中。

如下图,我已经把pm2的路径添加到环境变量~/.bash_profile,是不是有可能ansible的shell模块执行时候没有读取到环境变量?


2. 尝试在ansible的shell的执行参数加上. ~/.bash_profile,保证执行命令前先读取到环境变量。

执行成功!看来ansible在执行shell命令的时候,没有正确加载到~/.bash_profile。

那到底为什么没法正确加载到~/.bash_profile呢? 

原因

我在网上搜索了一下~/.bash_profile,发现linux里面有多个读取环境变量的配置文件,并且有加载顺序和不同的场景。

首先介绍两个概念:login shell和non-shell shell,顾名思义,一个是交互式的shell,一个是非交互式的shell。

login shell:通常指的是常规登录到某shell环境后,能够在当前命令行中输入shell命令这种情况。

non-login shell:不用登陆的,比如ssh远程执行,是非交互式的。

如下是login shell和non-login shell的环境变量文件的加载顺序。

由图片我们可知,ansible这种非交互式的shell执行应该读取的是~/.bashrc,而我这里配置到了~/.bash_profile 

解决方案

1. 将~/.bash_profile中ansible所需要的环境变量配置到~/.bashrc中

2. 在使用pm2的时候加上pm2的绝对路径

3. 在执行pm2的时候,在前面加上. ~/.bash_profile

比较推荐的是第一种方式,这样ansible后续有其他的环境变量也可以预先配置到~/.bashrc,减小我们改造或者书写ansible命令的成本。


备注:图片引用博客地址:https://blog.csdn.net/gatieme/article/details/45064705


博主:测试生财

座右铭:专注测试与自动化,致力提高研发效能;通过测试精进完成原始积累,通过读书理财奔向财务自由。

csdn:https://blog.csdn.net/ccgshigao

博客园:https://www.cnblogs.com/qa-freeroad/

51cto:https://blog.51cto.com/14900374