如何在移除设备时启动systemd用户服务,插入设备时停止?
实现设备移除启动、插入停止的用户服务逻辑
1. 解决udev操作用户服务的上下文问题
udev运行在系统级上下文,默认无法直接访问用户的systemd会话,必须指定用户的XDG_RUNTIME_DIR环境变量,确保systemctl --user能定位到用户的systemd实例。可以通过动态获取目标用户UID来设置该变量,或直接硬编码用户UID(比如常见的1000)。
2. 编写udev规则
创建规则文件(如/etc/udev/rules.d/99-reverse-device-trigger.rules),替换其中的设备匹配条件为你的设备属性:
# 设备插入时停止用户服务 ACTION=="add", SUBSYSTEM=="usb", ATTRS{idVendor}=="1234", ATTRS{idProduct}=="5678", RUN+="/bin/sh -c 'uid=$(id -u your-username); XDG_RUNTIME_DIR=/run/user/$uid systemctl --user stop reverse-device.service'" # 设备移除时启动用户服务 ACTION=="remove", SUBSYSTEM=="usb", ATTRS{idVendor}=="1234", ATTRS{idProduct}=="5678", RUN+="/bin/sh -c 'uid=$(id -u your-username); XDG_RUNTIME_DIR=/run/user/$uid systemctl --user start reverse-device.service'"
关键说明:
- 替换
your-username为实际用户名,或直接写UID(如uid=1000)提升效率 - 设备匹配条件需根据实际设备调整,可通过
udevadm info -a /dev/your-device获取设备属性 - 若仅针对特定用户触发,可添加
USER=="your-username"到规则中
3. 编写用户服务文件
创建用户服务文件(如~/.config/systemd/user/reverse-device.service):
[Unit] Description=反向触发服务(设备移除启动,插入停止) StopWhenUnneeded=no # 禁用默认自动停止逻辑,避免服务被意外终止 [Service] Type=simple ExecStart=/path/to/your/script.sh Restart=no # 根据需求调整重启策略
关键说明:
- 替换
/path/to/your/script.sh为实际要运行的脚本或命令 StopWhenUnneeded=no确保服务不会因依赖缺失自动停止,完全由udev控制启停
4. 重载配置并测试
- 重载udev规则:
sudo udevadm control --reload-rules
- 重载用户systemd配置并验证服务可用性:
systemctl --user daemon-reload systemctl --user start reverse-device.service systemctl --user stop reverse-device.service
- 测试设备插入/移除,检查服务状态:
systemctl --user status reverse-device.service
替代方案:用systemd.path监听设备节点
若不想在udev规则中直接执行命令,可依赖systemd的路径监听功能:
- 创建用户path文件
~/.config/systemd/user/reverse-device.path:
[Path] PathExists=/dev/your-device-node # 替换为设备的节点路径 [Install] WantedBy=default.target
- 修改服务文件添加冲突与依赖:
[Unit] Description=反向触发服务 Conflicts=reverse-device.path StopWhenUnneeded=no [Service] Type=simple ExecStart=/path/to/your/script.sh [Install] WantedBy=reverse-device.path
逻辑说明:
- 设备插入时,
/dev/your-device-node存在,reverse-device.path激活,触发服务停止(因Conflicts配置) - 设备移除时,
/dev/your-device-node消失,reverse-device.path停止,服务自动启动(因WantedBy配置)
内容的提问来源于stack exchange,提问作者V_V
相关产品推荐
相关产品推荐

