ttyUSB0 可用后运行服务

ttyUSB0 可用后运行服务

我制作了一个 systemd 服务,它启动一个简单的 .sh 来从串行连接读取数据。如果我在启动后手动运行该服务,它工作正常,但是当我尝试在启动时自动运行它时,它会失败,因为 .sh 还无法从 ttyUSB0 ( awk: fatal: cannot open file /dev/ttyUSB0' for reading (No such file or directory) 读取。

有没有办法让服务等待 ttyUSB0 然后运行 ​​.sh?我尝试了类似 after=ttyUSB0 的方法,但这不起作用。

[Unit] 
Description=Serial logger

[Service] 
ExecStart=/serial_script.sh

[Install] 
WantedBy=default.target

答案1

考虑使用udev规则而不是systemd服务来启动脚本。没关系,因为不建议从 udev 启动长时间运行的进程,并且较新的 udev 版本可能会主动尝试通过对 udev 事务和由它们生成的进程设置严格的时间限制来阻止这种情况。

但是,如果您需要在 udev 中执行此操作(例如,在具有旧版本的旧系统中),则应该可以使用systemd类似以下内容:/etc/udev/rules.d/99-serial-logger.rules

SUBSYSTEM=="tty", ACTION=="add", KERNEL=="ttyUSB0", RUN+="/serial_script.sh"

当将此作为 systemd 服务实现时(当前推荐的方式),请WantedBy=default.target从您的服务中删除该行并制定udev如下规则:

SUBSYSTEM=="tty", KERNEL=="ttyUSB0", TAG+="systemd", ENV{SYSTEMD_WANTS}+="your-serial-logger.service"

因此,udev应该告诉systemd在设备出现时启动服务,并在设备被删除时停止服务。

答案2

UDEV 中的此类规则不起作用

SUBSYSTEM=="tty", ACTION=="add", KERNEL=="ttyUSB0", RUN+="/serial_script.sh"

用于serial_script.sh | at now运行与 udev 进程分离的作业。 UDEV 会阻止您在 RUN 或 PROGRAM 脚本中启动长期存在的后台进程。但是,执行此操作的“正确方法”是使用 systemd。我推荐阅读使用 systemd 实例化服务在 udev 事件上启动长时间运行的 systemd 服务的正确方法从 udev 启动设备的 systemd 服务实例

相关内容