systemd启动调用Python脚本的Bash服务运行异常求助
问题原因
分两个阶段的错误分别说明:
第一阶段:CHDIR 200报错
- systemd对服务单元名称严格区分大小写,你最初的服务注册/配置存在大小写不一致(日志中显示为
poolBoy.service,实际文件名为poolboy.service),同时你修改服务文件后没有执行systemctl daemon-reload重载配置,导致systemd读取了旧的缓存配置,无法找到配置中指定的工作目录,触发切换目录失败错误。你修正服务名大小写后,systemd加载了正确的路径配置,该错误自然消失。
第二阶段:服务启动后立刻标记为Succeeded、循环重启
核心问题出在启动脚本和服务配置的逻辑错误:
- 多余的sudo调用触发权限限制:systemd启动服务时默认使用root身份运行,你在启动脚本最后额外加
sudo启动Python进程完全没有必要。多数Linux发行版默认开启sudo requiretty配置,要求sudo必须在关联控制终端的环境下执行,而systemd启动的进程没有控制终端,导致sudo命令直接报错退出,Python进程根本没有被启动。 - 主进程跟踪失效:sudo退出后,启动脚本直接执行到末尾正常退出,systemd检测到主进程(即启动脚本进程)退出且退出码为0,就判定服务执行成功,结合你配置的
Restart=always规则,等待重启间隔到了就再次拉起服务,形成无限循环。 - 日志中出现的
dwc_otg_hcd_urb_dequeue警告是树莓派USB控制器通信超时,一般是外接USB设备接触不良、供电不足导致,和服务启动失败没有直接关系。
解决步骤
1. 修正systemd服务配置
首先修改你的poolboy.service文件,调整为如下内容,注意自定义服务不要放在/lib/systemd/system/目录(该目录存放系统/包管理器安装的原生服务),应该放到/etc/systemd/system/目录下:
[Unit] Description=Pool Boy After=network-online.target Wants=network-online.target [Service] Type=simple User=pi WorkingDirectory=/home/pi/poolboy ExecStart=/home/pi/poolboy/start StandardOutput=journal StandardError=journal Restart=always RestartSec=5 [Install] WantedBy=multi-user.target
配置说明:
- 加
Wants=network-online.target确保网络服务真正就绪后再启动服务,避免网络依赖问题 - 指定
User=pi用普通用户运行服务,避免root权限带来的环境、安全问题,如果需要操作GPIO/USB等硬件,提前把pi用户加入对应用户组即可 - 日志输出改为journald,后续可以直接用
journalctl -u poolboy.service查看所有应用日志,排查问题更方便 - 显式指定
RestartSec=5,设置合理的重启间隔,避免重启过于频繁
2. 修正应用启动脚本
修改/home/pi/poolboy/路径下的start启动脚本,去掉多余的sudo,用exec替换进程启动方式,让systemd可以正确跟踪到Python主进程的状态:
#!/bin/bash cd "$(dirname "$0")" VENV=venv echo "checking for $VENV" if [ ! -d "$VENV" ] then echo "$VENV does not exist... initially creating it" python3 -m venv "$VENV" echo "activating the virtual environment" source "$VENV/bin/activate" echo "installing libraries from requirements.txt" pip3 install -r requirements.txt else source "$VENV/bin/activate" fi echo "starting..." # 去掉sudo,用exec将当前shell进程替换为Python进程,避免脚本提前退出 exec "$VENV/bin/python3" poolboy.py --standalone
注意所有路径变量都加双引号包裹,避免路径有空格时出现解析错误。
3. 修正enable安装脚本
在安装脚本中加重载配置的步骤,确保systemd加载最新的服务文件:
#!/bin/bash sudo cp /home/pi/poolboy/service/poolboy.service /etc/systemd/system/ sudo systemctl daemon-reload sudo systemctl enable poolboy.service
4. 重新部署验证
按顺序执行以下命令完成重新部署:
- 停止旧的异常服务:
sudo systemctl stop poolboy.service - 运行enable脚本重新注册服务
- 启动服务:
sudo systemctl start poolboy.service - 查看服务运行状态:
sudo systemctl status poolboy.service - 实时查看应用日志排查问题:
journalctl -u poolboy.service -f
可选优化
如果日志中的USB超时警告影响外接硬件正常使用,可以检查USB线材连接是否牢固、树莓派电源功率是否足够,避免低压导致USB设备工作异常。
内容的提问来源于stack exchange,提问作者jordanthompson
相关产品推荐
相关产品推荐

