我有一个 Python 脚本,它通过打开其 /dev/ttyUSBx 串行端口文件、发送关闭 AT 命令、等待响应,然后通过监视串行端口文件的消失来等待调制解调器关闭来重新启动 GSM 调制解调器之后,GPIO 引脚用于物理关闭调制解调器,然后再次打开。
该脚本在独立运行时工作正常。然后我尝试使用 systemd 将其变成一次性服务,如下所示:
[Unit]
Description=Modem Restart Service
[Service]
Type=oneshot
ExecStart=/usr/bin/env python3 modem-restart.py
[Install]
WantedBy=multi-user.target
但是,当尝试启动该服务时,它总是失败并出现以下错误:
Apr 02 09:34:21 test-system systemd[1]: Starting Modem Restart Service...
-- Subject: Unit RestartModem.service has begun start-up
-- Defined-By: systemd
-- Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
--
-- Unit RestartModem.service has begun starting up. Apr 02 09:34:22 test-system InternetMonitor.exe[5601]: INFO:root:Sending shutdown command to modem... Apr 02 09:34:36 test-system systemd[1]: RestartModem.service: Main process exited, code=killed, status=1/HUP Apr 02 09:34:36 test-system systemd[1]: Failed to start Modem Restart Service.
-- Subject: Unit RestartModem.service has failed
-- Defined-By: systemd
-- Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
--
-- Unit RestartModem.service has failed.
--
-- The result is failed. Apr 02 09:34:36 test-system systemd[1]: RestartModem.service: Unit entered failed state. Apr 02 09:34:36 test-system systemd[1]: RestartModem.service: Failed with result 'signal'.
谁能解释一下错误的原因是什么?
答案1
经过进一步调查,问题似乎源于以下事实:当调制解调器与 USB 端口1断开连接时,程序对串行端口设备文件有一个打开的文件句柄。我的猜测是内核发送 SIGHUP 让程序知道断开连接。 Python 处理得很好,没有任何错误,程序正常执行时也没有任何问题。然而,systemd 似乎拦截了 SIGHUP 信号并将其视为失败,从而杀死了程序。修改程序以使其工作方式不同就绕过了这个问题。
1:保持文件句柄打开的原因是,在发送关闭命令后,程序会等待,直到调制解调器向它发送一条消息,表明它已完全关闭。不幸的是,调制解调器在发送消息后立即断开与 USB 的连接,这没有给程序足够的时间来解析响应,然后关闭文件句柄。