树莓派4B升级Bullseye后@reboot定时任务无法访问网络
问题分析与解决方案
问题根源
升级到Raspberry Pi OS Bullseye后,crontab的@reboot任务会在系统启动早期触发执行,此时网络服务(包括接口IP获取、网络连接建立)还未完全就绪,导致脚本尝试访问MariaDB或MQTT broker时抛出OSError: [Errno 101] Network is unreachable错误。而命令行直接运行时网络已稳定,因此不会出现该问题。
解决方案
方法1:给crontab任务添加延迟
在@reboot指令后增加sleep命令,让脚本等待一段时间再执行,确保网络就绪:
@reboot sleep 30 && python -u /home/pi/bin/mqttSRV_ControlLightsFR.py >> /home/pi/ControlLightsFROut.txt 2>&1
- 注意:延迟时间可根据实际网络初始化速度调整(10-60秒不等),缺点是无法精准匹配网络就绪的时间点。
方法2:改用systemd服务(推荐)
systemd支持配置服务依赖网络就绪后再启动,比crontab更可靠:
- 创建服务文件:
sudo nano /etc/systemd/system/control-lights.service
- 写入以下内容:
[Unit] Description=Control Lights MQTT Service After=network-online.target Wants=network-online.target [Service] User=pi ExecStart=/usr/bin/python -u /home/pi/bin/mqttSRV_ControlLightsFR.py Restart=on-failure RestartSec=5 StandardOutput=append:/home/pi/ControlLightsFROut.txt StandardError=inherit [Install] WantedBy=multi-user.target
- 启用并启动服务:
sudo systemctl daemon-reload sudo systemctl enable control-lights.service sudo systemctl start control-lights.service
After=network-online.target确保服务在网络完全就绪后启动,Restart=on-failure可在脚本崩溃时自动重启。
方法3:在Python脚本内部添加网络检查
在脚本开头加入循环逻辑,直到网络能正常连接目标服务再执行后续代码:
import socket from time import sleep def wait_for_network(broker_address, broker_port, timeout=5): while True: try: # 尝试连接MQTT broker验证网络 sock = socket.create_connection((broker_address, broker_port), timeout=timeout) sock.close() print("网络已就绪") break except OSError: print("网络未就绪,等待5秒重试...") sleep(5) # 替换为你的MQTT broker地址和端口 wait_for_network("你的broker地址", 1883) # 后续原有业务逻辑 # ...
内容的提问来源于stack exchange,提问作者GaryG
相关产品推荐
相关产品推荐

