如何基于libinput设备状态流触发systemctl启停iio-sensor-proxy服务?
解决平板模式切换时自动启停iio-sensor-proxy服务的问题
一、实现需求的完整脚本
要实现当平板模式state变为1时启动服务,变为0时停止服务,我们可以写一个bash脚本,直接监听libinput的输出并处理每一行事件:
#!/bin/bash # 定义监听的设备路径 DEVICE="/dev/input/by-path/pci-0000:00:1f.0-platform-INT33D6:00-event" # 持续监听设备事件,确保输出行缓冲避免延迟 stdbuf -oL -eL libinput debug-events --device "$DEVICE" | while read -r event_line; do # 筛选出SWITCH_TOGGLE事件 if echo "$event_line" | grep -q "SWITCH_TOGGLE"; then # 提取最后一个字段(state值) state=$(echo "$event_line" | awk '{print $NF}') echo "$(date '+%Y-%m-%d %H:%M:%S') - 检测到平板模式切换: state = $state" # 根据state执行服务操作 if [ "$state" -eq 1 ]; then echo "启动iio-sensor-proxy服务..." sudo systemctl start iio-sensor-proxy.service elif [ "$state" -eq 0 ]; then echo "停止iio-sensor-proxy服务..." sudo systemctl stop iio-sensor-proxy.service fi fi done
关键说明:
stdbuf -oL -eL:强制libinput的标准输出和错误输出为行缓冲,确保事件能实时传递到后续处理,不会因为块缓冲导致延迟。- 直接在
while循环中处理每行输出,避免额外的grep子进程带来的缓冲问题(这也是Andrew脚本出问题的核心原因)。 awk '{print $NF}':简单高效地提取每行的最后一个字段(也就是state值)。- 注意:执行
systemctl命令需要sudo权限,所以运行脚本时要么用sudo ./your-script.sh,要么给当前用户配置systemctl操作的免密权限(可以通过编辑/etc/sudoers文件实现)。
二、Andrew的脚本无输出的原因及修复
Andrew的脚本如下:
#!/bin/bash stdbuf -oL -eL libinput debug-events --device /dev/input/by-path/pci-0000:00:1f.0-platform-INT33D6:00-event | grep SWITCH_TOGGLE | while read string; do echo "$string"; done
问题出在**grep的缓冲机制上:虽然给libinput加了行缓冲,但当grep的输出不是终端(而是管道到while循环)时,它默认会使用块缓冲**——只有当缓冲区填满(通常是4KB或8KB)时才会输出内容,所以你看不到实时的事件输出。
修复方法:给grep也加上行缓冲
修改后的脚本:
#!/bin/bash stdbuf -oL -eL libinput debug-events --device /dev/input/by-path/pci-0000:00:1f.0-platform-INT33D6:00-event | stdbuf -oL grep SWITCH_TOGGLE | while read string; do echo "$string"; done
通过stdbuf -oL强制grep使用行缓冲,这样每匹配到一行SWITCH_TOGGLE事件就会立即输出,while循环就能实时处理了。
额外建议:让脚本开机自启
如果希望这个切换逻辑在系统启动时自动运行,可以把它做成一个systemd服务:
- 创建服务文件
/etc/systemd/system/tablet-mode-handler.service,内容如下:
[Unit] Description=Tablet Mode Switch Handler After=multi-user.target [Service] Type=simple ExecStart=/path/to/your/script.sh # 替换成你的脚本实际路径 User=root Restart=always # 意外退出时自动重启 [Install] WantedBy=multi-user.target
- 启用并启动服务:
sudo systemctl daemon-reload sudo systemctl enable --now tablet-mode-handler.service
这样系统每次启动都会自动运行这个脚本,监听平板模式切换事件。
内容的提问来源于stack exchange,提问作者La faguette
相关产品推荐
相关产品推荐

