通过systemd启动Python脚本logdl.py时触发AssertionError,手动启动无异常
这种情况我碰到过好几次,大概率是systemd的执行环境和你手动命令行的环境不一致导致的——哪怕都是root用户,两者的工作目录、环境变量、启动时机都有差异,给你几个实用的排查方向:
先确认工作目录是否匹配:systemd默认会在
/根目录下执行脚本,而你手动运行时肯定是在脚本所在的目录里。很多脚本会依赖当前目录下的配置、临时文件或者相对路径的资源,这时候就容易触发断言错误。你可以在systemd服务的[Service]区块里加上:WorkingDirectory=/绝对路径/到/你的脚本所在文件夹核对环境变量差异:手动运行时的
PATH、PYTHONPATH这些环境变量,和systemd启动时的默认环境可能不一样,尤其是如果你用了pipenv管理Python环境,systemd可能找不到正确的解释器。建议:- 在
[Service]里明确指定环境变量,比如把你手动运行时echo $PATH的输出内容加进去:Environment="PATH=/home/你的用户名/.local/bin:/usr/bin:/bin" - 也可以在logdl.py开头加一段代码打印环境变量,对比两种启动方式的差异:
然后用import os print("当前环境变量:", os.environ)journalctl -u 你的服务名查看systemd启动时的输出,和手动运行的输出对比,就能找到不一样的地方。
- 在
检查systemd服务的ExecStart配置:确保你在
ExecStart里用了绝对路径的Python解释器和脚本,比如你手动用pipenv run python logdl.py,那systemd里应该写成:ExecStart=/home/你的用户名/.local/bin/pipenv run python /绝对路径/到/logdl.py绝对不要用相对路径,否则systemd可能找不到对应的文件或命令。
排查串口相关的启动时机问题:从你给出的错误截图看,AssertionError出现在
serial.serialutil里,大概率和串口设备有关。systemd启动服务的时机可能比串口设备就绪的时间早,你可以在[Unit]区块里加上依赖,确保设备就绪后再启动服务:Requires=dev-ttyUSB0.device After=dev-ttyUSB0.device这里的
dev-ttyUSB0.device要换成你实际使用的串口设备(可以用ls /dev/tty*查看具体名称)。
你可以先从这几个方向逐一排查,应该能快速定位问题~
备注:内容来源于stack exchange,提问作者Kris Rice

