这是在工作中遇到的问题,记录一下。
原本我是想让我的程序能开机自启动和程序崩溃后能自启动,所以我写了一个sh脚本,通过命令捕获程序的进程,如果能捕获到,说明程序是在运行中,那就不做操作;如果没有捕获到,那就重启程序。然后用crontab -e,在文档最后一行添加定时任务,让系统没分钟执行一下这个sh脚本,起到监控程序的作用。

我在crontab -e中是这样添加定时任务的:

* * * * * /bin/bash /home/lishanlu/code/openmv_city/run.sh

说明一下,我的系统版本:Ubuntu 18.04.5 LTS (GNU/Linux 4.15.0-161-generic x86_64)。我在终端上,直接输入命令bash /home/lishanlu/code/open_city/run.sh是能启动程序的,所以可以保证我的run.sh脚本写的没有问题。但添加进crontab定时任务后就是没有看到程序启动。

调试找到原因的几个方面

  • 1、cron是否正常启动
    crontab不是Linux内核的功能,而是依赖一个cron服务,这个服务可以启动当然也可以停止,但是一般情况下cron服务是开机自启动的。如果停止了就无法执行任何定时任务了,解决的方法是打开它。
    查询cron运行状态:
systemctl status cron
或者
systemctl status cron.service

查看开机自启动服务里面有没有cron服务,运行命令:

sudo sysv-rc-conf

可以看到如下结果:

crontab echo命令不报错也不执行 crontab -e不执行_bash


最上面service一行对应的是服务器开启级别(可参考Linux常用命令):我们常用3,5,只要3,5对应的列有x,就代表开机自启动了。可以看到cron服务有设定开机自启动。

如果cron服务有设定开机自启动,但查看状态又没有启动,我们可以手动启动它。

service cron start
  • 2、添加运行日志,定位错误所在
* * * * * /bin/bash /home/lishanlu/code/openmv_city/run.sh >> /home/lishanlu/code/openmv_city/crontab_log.log 2>&1

把执行的日志重定向保存好,可以很方便看到到底是没执行,还是执行出错。

  • 3、添加简单的定时任务,确实crontab是否正常运行
* * * * * echo “hello world” >> /home/lishanlu/code/openmv_city/test.txt

这个定时任务是每分钟向test.txt中写入“hello world”

  • 4、sh脚本是否需要特定权限才能执行?
    运行命令chmod,增加文件执行权限
chmod +x /home/lishanlu/code/openmv_city/run.sh
  • 5、路径问题不对?
    有的命令在shell中执行正常,但是在crontab执行却总是失败。有可能是因为crontab使用的sh未正确识别路径,最好都用绝对路径。
  • 6、在crontab中,有些系统命令被隔绝,导致调用出错
    如果我们的运行程序中需要调用系统命令,在crontab中是直接调用不了的,比如ifconfig,需要在运行程序中用绝对路径/sbin/ifconfig来调用
  • 7、crontab中不会用你的虚拟python解释器,要绝对路径指定出来
    比如我的service_app.py需要用到我的py36虚拟环境,如果定时任务这样写就会导致有些python包导入不了,因为crontab下,默认用系统自带的python环境。
# 这样写会报错,这里调用的python解释器不是我所需要的虚拟环境py36中的python解释器
* * * * * python /home/lishanlu/code/openmv_city/service_app.py

应该这样写:

* * * * * /home/lishanlu/anaconda3/envs/py36/bin/python /home/lishanlu/code/openmv_city/service_app.py

或者在运行之前加入环境变量PATH也可以:

* * * * * export PATH=/home/lishanlu/anaconda3/envs/py36/bin/:$PATH; python /home/lishanlu/code/openmv_city/service_app.py