树莓派Ubuntu20.04 Crontab @reboot无法启动第二个Py脚本
问题原因
这个问题是crontab执行环境和手动终端执行环境的差异,叠加当前启动逻辑的缺陷导致的,核心原因两点:
- crontab的进程组回收机制:crontab运行@reboot任务时,会在任务主进程(也就是你的start.py)退出后,直接清理整个进程组下的所有子进程。你在两个启动命令后都加了
&把进程放后台,start.py执行完两行os.system代码就会立刻退出,此时第二个脚本还在加载初始化阶段,直接就被crontab发的终止信号杀掉了;第一个脚本因为启动速度快,初始化完成躲过了回收,所以能正常运行。 - 运行环境不一致:crontab的运行环境是极简的,和你手动登录终端的环境差异很大:
- 默认PATH只有
/usr/bin:/bin,如果你的python解释器、脚本依赖的命令装在其他路径,会报找不到命令的错误 - 默认工作目录是执行crontab的用户的家目录,如果你的两个子脚本里用了相对路径读写文件,会因为路径不存在报错
- crontab任务没有绑定交互终端,脚本如果有读取终端输入的逻辑会直接崩溃
- 默认PATH只有
解决方案
按可靠性从低到高给三个可直接落地的方案:
方案1:修改start.py适配crontab环境
把start.py改成如下内容,核心是先切换到正确工作目录,用nohup让子进程脱离当前会话不被回收,同时把日志输出到固定文件方便排错:
import os import time # 切换到脚本所在目录,解决相对路径问题 os.chdir("/home/okay") # 启动第一个脚本,nohup忽略挂起信号,标准输出、错误信息都写入日志 os.system("nohup python3 /home/okay/avadot.py > /home/okay/avadot.log 2>&1 &") # 间隔1秒给第一个脚本留初始化时间,避免资源抢占 time.sleep(1) # 启动第二个脚本 os.system("nohup python3 /home/okay/main.py > /home/okay/main.log 2>&1 &")
同时修改crontab规则,把python3换成绝对路径(先执行which python3拿到你系统里python3的完整路径,比如返回/usr/bin/python3就用这个值),避免找不到命令:
@reboot sleep 300 && /usr/bin/python3 /home/okay/start.py
方案2:跳过start.py,直接在crontab配置两个启动任务
这种方式少了一层脚本调用,逻辑更简单,不容易出问题。直接编辑crontab删掉原来的@reboot规则,换成下面两条:
@reboot sleep 300 && cd /home/okay && nohup /usr/bin/python3 /home/okay/avadot.py > /home/okay/avadot.log 2>&1 & @reboot sleep 300 && cd /home/okay && nohup /usr/bin/python3 /home/okay/main.py > /home/okay/main.log 2>&1 &
方案3:用systemd配置开机自启(最推荐,Ubuntu下最稳定)
crontab本身设计就不是用来跑常驻服务的,用systemd管理常驻脚本不会有进程回收问题,还自带崩溃自动重启、日志查询能力,不需要写sleep等待系统加载:
- 创建第一个服务配置文件,执行
sudo nano /etc/systemd/system/avadot.service,写入以下内容(注意把User改成你实际运行脚本的用户名,这里默认是okay):[Unit] Description=Avadot background service After=network.target [Service] User=okay WorkingDirectory=/home/okay ExecStart=/usr/bin/python3 /home/okay/avadot.py Restart=always RestartSec=10 [Install] WantedBy=multi-user.target - 创建第二个服务配置文件,执行
sudo nano /etc/systemd/system/maindot.service,写入:[Unit] Description=Main background service After=network.target avadot.service [Service] User=okay WorkingDirectory=/home/okay ExecStart=/usr/bin/python3 /home/okay/main.py Restart=always RestartSec=10 [Install] WantedBy=multi-user.target - 执行以下命令加载配置、设置开机自启、立即启动服务:
sudo systemctl daemon-reload sudo systemctl enable avadot.service maindot.service sudo systemctl start avadot.service maindot.service
后续如果要查看脚本运行日志,直接执行journalctl -u avadot.service或者journalctl -u maindot.service即可,不需要自己额外收集日志。
排错提示:如果配置完还是有脚本没启动,优先看脚本对应的日志文件或者systemd日志,90%以上的问题都是文件权限不足、相对路径写错、依赖包没装对导致的。
内容的提问来源于stack exchange,提问作者ta2bss
相关产品推荐
相关产品推荐

