CrazyAirhead

疯狂的傻瓜,傻瓜也疯狂——傻方能执著,疯狂才专注!

0%

碰到的两个与 Shell 相关的小问题

说明

这次碰到的两个问题,解决后发现都不是什么大问题,解决的方法很简单,但没找到原因前确实花了不少时间进行排查,因此记录下来,方便日后查看。

问题1

Jenkins 编译,通过脚本发布 jar 程序,虽然提示编译成功,但应用未正常启动,通过ps 查看不到对应的进程。

Jenkins 的编译配置是从其他项目克隆过来的,执行正常,区别只是原来的部署脚本,原来是是 Docker 部署,新项目是直接虚机部署。编写的脚本除去一些进程的判断,大致是这样的,看似也不存在问题,另外在终端直接执行脚本是应用是可以正常启动的。

1
nohup java -jar app.jar > out.log 2>&1 &

因为通过 Jenkins 发布就是启动不了。虽然直接执行脚本是可以的,但避免有什么未知问题,还是在脚本中增加了echo 逐条写日志,日志也都有正常打印出来。后来干脆把启动程序的日志的重定向也去掉,此时在 Jenkins 的编译日志中是能看到应用已经启动了,但 Jenkins编译成功后,应用依然没有正常启动。此时能想到的就是nohup没有加&,终端退出应用就结束的情况。

初步开始怀疑 Jenkins 做了手脚,经过一方搜索,发现通过 Shell 脚本发布时,会衍生进程,Jenkins 默认会杀掉衍生进程。需要增加BUILD_ID=DONTKILLME防止衍生进程被杀。可以增加在 Jenkis中,或者增加的执行的脚本中。

1
2
3
BUILD_ID=DONTKILLME
```bash
nohup java -jar app.jar > out.log 2>&1 &

调整后一切正常。那为什么使用 Docker 部署正常呢?Docker容器启动不是 Shell 脚本的衍生进程。

# 问题2

因为项目采用了 Docker 部署,因为Docker的隔离性,容器内的应用无法操作宿主机,因此通过SSH连接宿主机,执行宿主机的命令并生成文件。这个部署在开发机一个正常的功能,在部署到另一台测试机后无法正常使用。

初步排查的时候只知道文件未正常生成,因为执行的命令依赖一个环境变量`HOME`,在终端中变量是有设置的,且其他目录也没有找到生成的文件。

因为一开始没有增加日志,于是重新增加日志打印,日志正常打印。继续增加 SSH 的返回值,返回的 exit code 是 0,返回结果是空,说明需要执行的命令是正常执行的。增加打印SSH 执行的命令,命令在终端里是可以正常生成文件的。

于是就有被带歪了,就开始想会不会因为封装的SSH的配置有问题,修改各种配置都测试了下,还是没有结果。

重新静下来思考,要不把依赖的变量,替换成实际的路径看看,于是多增加执行一个SSH 命令,`echo $HOME`,并增加了对应的日志打印。结果发现程序中无法读取环境变量`HOME`,于是确认`HOME`是配置的`/etc/profile`中的,重新source,不行,重启机器,依然不行。

后面修改成在`~/.bashrc`中配置,可以正常读取。

# 小结

两个问题都不难,但都属于自己的只是盲区。虽然能使用Jenkins进行编辑发布,虽然可以使用Jsch执行ssh命令,但只是凑巧起作用而已,稍微碰点以为情况就歇菜了,还是等多读文档。

欢迎关注我的其它发布渠道