事情的经过大概是这样的,我正坐在工位安逸的看优快云的时候:
简言之就是某人写了一个脚本,写好之后./xxx.sh可以正常执行,可以生产目标数据,但是嘞需求是要求Linux每两分钟运行一次,这个时候就要在Linux上设置定时任务;这个时候问题来了,我定时任务搞好了,并且crontab日志显示定时任务也在执行,可是我的目标数据就是出不来。所以,我大概奋斗了一天,最终问题告破。
我们来捋捋这个问题,
首先第一步是我的脚本执行ok,可以正常执行,正常生产;
第二步,我去查看定时任务;
crontab -e //编辑定时任务
or
crontab -l //查看定时任务
可以看到进程中有两个定时任务,校验一下语法发现无异常;
第三步,瞅一瞅定时任务的执行日志;
tail -f /var/log/cron
这里动态查询定时日志,发现无异常,都在正常执行,这里说明一下要在root下查看日志,我定时是在我的子用户上,所以root这里的定时任务较多,不要看到多就焦虑!!!
这里发现子用户的定时任务在正常执行;
第四步,诡异的事情就是啥都没问题,为啥不行!
这里笼统解释下,就是说我们正常执行脚本的时候,环境变量这个东西是登录服务器的时候自动就加载好的,但是嘞,crontab在定时执行的时候对于环境变量加载是不完全的,所以就导致执行脚本文件的时候,由于环境变量的缺失,不能够正常运行脚本(这一点可以在写脚本的时候注意生成错误日志,否则排查的时候比较困难,就像这种)。
这里对于这种问题,菜鸟给了三个解决方案,这里借鉴下:
1.所有命令需要写成绝对路径形式,如:
/usr/local/bin/docker
2.在 shell 脚本开头使用以下代码:
#!/bin/sh
. /etc/profile
. ~/.bash_profile
(这里注意下,"."后和"/"中间有空格,合理的格式"."在vim下会变成黄色)
3、在 /etc/crontab 中添加环境变量,在可执行命令之前添加命令 . /etc/profile;/bin/sh,使得环境变量生效,例如:
20 03 * * * . /etc/profile;/bin/sh /var/www/runoob/test.sh
这里看完估计80%的问题基本就解决了;(然而mmp,我的问题仍然没有解决)
于是乎,第五步,我开始了各种疯狂的尝试;
开始怀疑脚本问题,苦于不太懂别人写的脚本,我备份完了之后就开始修改脚本内的路径啊,环境变量啊,各种东西,甚至我把JAVA的环境变量都导入了脚本里面,结果都是无功而返。然后我开始冷静分析,分析脚本针对的具体应用,以及脚本用到的包文件路径,包括脚本的细致分析;后来发现脚本中使用了大量的":../"这种操作,大致就是返回上一级目录,于是乎我旁边的大神脑洞大开,说道:"要不你直接在脚本里把路径切过去试试!",我一想,这能行嘛,不是瞎搞;然后就然后,事实告诉我,他可不是瞎搞,他那是有备而来。终于在下面这条语句的加持下,它成了,它成了!!!
总结:
以后遇到这种问题,务必先将前四步仔细检查,无有纰漏之后,就要去分析脚本的实际运行情况了,就像我这种,别人的脚本我看不懂,我就不去看,所以搞了一天也是无用功,实在没办法了才去看脚本;所以大家遇到此类问题的时候,一定要认真分析,特别是脚本的具体细节,路径之类的,仔细检查!