![在 systemd 服务文件中,如何说“USB 准备就绪后”?](https://linux22.com/image/1560977/%E5%9C%A8%20systemd%20%E6%9C%8D%E5%8A%A1%E6%96%87%E4%BB%B6%E4%B8%AD%EF%BC%8C%E5%A6%82%E4%BD%95%E8%AF%B4%E2%80%9CUSB%20%E5%87%86%E5%A4%87%E5%B0%B1%E7%BB%AA%E5%90%8E%E2%80%9D%EF%BC%9F.png)
我有一个在 Raspbian Stretch 上运行的程序,通过 USB 与手机通信,使用在 libusb 之上实现的专门协议。
我希望程序在启动时运行,因此我创建了一个 systemd 服务文件,但不确定它应该在什么目标之后运行:
[Unit]
Description=My Program
After=network.target <-- ???
[Service]
ExecStart=/home/pi/myprogram
User=root
[Install]
WantedBy=multi-user.target
这个内容可以完成工作,但是正确之后应该是什么?我怎么能说“USB 准备就绪后”呢?
我在网上找到的大多数信息都是关于设置 udev 规则的,我的理解是在看到某个设备时加载内核模块,但我认为这不是我想要的。
任何帮助都将受到赞赏。
答案1
我之前没有解决过这个问题,但它似乎很适合“基于路径的激活”。
您不需要在服务文件中使用“After=”子句,而是可以创建一个.path
文件,如man systemd.path
。
/dev/bus/usb
在或下找到合适的文件/sys/bus/usb
,该文件的存在表明“USB 已启动”。然后使用您将要创建的文件systemd
监视文件路径。然后,当文件存在时,该文件将激活您的文件。.path
.path
.service
答案2
我要做的是创建一个systemd 设备单元使用 udev 规则。例如:使用/etc/udev/rules.d/20-usb-bus.rules
以下命令创建:
KERNEL=="usb[1-2]", TAG+="systemd"
在下次启动(或重新加载 udev 规则)时,您将拥有系统设备单元:
# systemctl status dev-bus-usb-001-001.device
● dev-bus-usb-001-001.device - 2.0 root hub
...
# systemctl status dev-bus-usb-002-001.device
● dev-bus-usb-002-001.device - 3.0 root hub
...
现在,您可以通过添加以下内容在 USB 总线准备就绪后启动您的服务:
[Unit]
...
After=dev-bus-usb-001-001.device dev-bus-usb-002-001.device
到你的 systemd 服务。