我正在运行一个守护程序,启动时需要设备的路径。该设备已连接到 USB 总线,但有时会断开 USB 并再次重新连接(连接器松动或硬件崩溃,尚未发现问题),但随后该设备会获得另一个名称,例如,/dev/ttyACM0
变为/dev/ttyACM1
。
它是一个虚拟串行端口,可从 AIS 接收器(感兴趣的 Quark-elec QK-A022)输出 NMEA 数据。
我非常确定只有一台设备会同时连接到 USB。
当系统中插入特定类型的设备时,有没有办法使用 systemd 启动/重新启动服务?我注意到systemctl list-units --type=device
其中列出了设备,所以我充满希望,但到目前为止我找到的每个示例都是基于显式启动 servicename@device 。
root@ais:/home/pi# systemctl list-units --type=device | fgrep STM
sys-devices-platform-soc-3f980000.usb-usb1-1\x2d1-1\x2d1.2-1\x2d1.2:1.0-tty-ttyACM1.device loaded active plugged STM32F407
我非常确定只有一台设备会同时连接到 USB。
答案1
如今,插入设备时运行守护程序的规范方法似乎是为守护程序创建一个 systemd 单元,并为引用该单元的设备添加一个 udev 条目。例如,/etc/udev/rules.d/90-my.rules
使用以下行创建一个文件
ACTION=="add", KERNEL=="ttyACM*", TAG+="systemd", ENV{SYSTEMD_WANTS}+="myacm@%k.service"
和一个文件/etc/systemd/system/[email protected]
[Unit]
Description=my serial daemon for ttyACM0
[Service]
ExecStart=/bin/myscript %i
您可能需要sudo udevadm control --reload
和sudo systemctl daemon-reload
。当您插入设备时,您的脚本应该使用参数运行(ttyACM0
如果这是它的名称)。检查日志文件中是否有错误。
参见man 7 daemon
部分新型守护进程和基于设备的激活, 也man systemd.device
。
答案2
我不知道您是否可以在 systemd 中执行此操作,但如果检测到设备更改,您可以使用 udev 重新启动/重新加载服务。