You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

树莓派开机启动Python脚本:如何让服务等待网络与GSM模块就绪?

解决systemd服务开机过早启动的问题(等待网络IP与GSM模块)

一、调整systemd服务的网络依赖

默认的network.target仅等待网络服务启动,不会确保系统获取到可用的非回环IP。修改服务文件,添加更严格的网络等待规则:

  1. 编辑你的服务文件(示例路径:/etc/systemd/system/my-server.service):
[Unit]
Description=My Python Server
# 等待网络完全联机状态
After=network-online.target
Wants=network-online.target
# 确保物理网卡(如wlan0/eth0)存在,排除仅依赖回环的情况
ConditionPathExists=/sys/class/net/wlan0/address

[Service]
Type=simple
ExecStart=/usr/bin/python3 /path/to/your/server.py
Restart=always
# 前置检查:循环等待直到获取到非回环IP
ExecStartPre=/bin/bash -c 'until hostname -I | grep -qE "([0-9]{1,3}\.){3}[0-9]{1,3}"; do sleep 1; done'

[Install]
WantedBy=multi-user.target
  • network-online.target:确保网络服务完全启动并完成IP分配
  • ConditionPathExists:验证物理网卡存在,避免服务仅依赖回环网卡启动
  • ExecStartPre脚本:通过hostname -I输出循环检查,直到获取到有效局域网IP

二、添加GSM模块初始化等待

根据你的GSM模块类型,选择以下一种检查方式:

方法1:检查设备节点存在

如果GSM模块通过USB连接,通常会生成/dev/ttyUSB0或/dev/ttyACM0设备节点,在服务的[Unit]段添加:

ConditionPathExists=/dev/ttyUSB0

方法2:验证模块响应AT指令

若需要确保模块完全初始化(能正常响应指令),在[Service]段添加前置检查脚本:

ExecStartPre=/bin/bash -c 'until echo -e "AT\r\n" > /dev/ttyUSB0 && timeout 2 grep -q "OK" < /dev/ttyUSB0; do sleep 2; done'

注意:需确保服务运行用户有权限访问设备节点,可将用户加入dialout组,或在[Service]段添加User=pi(以树莓派默认用户为例)

三、关于.socket单元的误区

你之前尝试的.socket单元适用于套接字激活场景:systemd先监听端口,有请求时再启动服务。但如果你的Python服务器需要主动绑定特定局域网IP,socket单元无法等待IP就绪后再执行绑定,反而会导致启动失败。因此,服务单元+ExecStartPre前置检查的方式更适配你的需求。

四、应用修改并测试

  1. 重新加载systemd配置:
sudo systemctl daemon-reload
  1. 重启服务验证规则:
sudo systemctl restart my-server.service
  1. 测试开机启动行为:
sudo reboot

重启后可通过journalctl -u my-server.service查看日志,确认服务是在网络与GSM模块就绪后才启动的。

内容的提问来源于stack exchange,提问作者Krupp J

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 23:27:25