这是我的/lib/udev/rules.d
目录中的一条规则:
SUBSYSTEM=="input", ATTRS{idVendor}=="045e", ATTRS{idProduct}=="008c", RUN+="/home/mikeknoop/scripts/udev-receiver.sh"
以下是该脚本的简单内容udev-receiver.sh
:
#!/bin/bash
echo "UDEV-RECEIVER INIT" >> /var/log/external.log
{
sleep 5;
echo "Done" >> /var/log/external.log
} &
echo "UDEV-RECEIVER FINISH" >> /var/log/external.log
当我插入设备时,输出external.log
正如您所期望的:
UDEV-RECEIVER INIT
UDEV-RECEIVER FINISH
Done
但是,我也跟踪了系统日志/var/log/syslog
并发现,尽管我已经分叉了长时间运行的sleep
进程,udev
但设备初始化仍然被阻止,直到它Done
出现在我的external.log
文件中。
这很重要的原因是因为我试图通过设置一些设备属性,但直到整个初始化完成(直到出现在之后)xinput
才列出该设备。xinput list
udev
Done
external.log
“将程序添加到要为特定设备执行的程序列表中。这只能用于运行时间非常短的任务。长时间运行事件进程可能会阻止此设备或相关设备的所有进一步事件。长时间运行的任务需要立即与事件进程本身分离。”
我无法将手册页与我看到的行为联系起来。有人能解释一下或提供更好的方法来在xinput
插入设备时设置属性吗?
谢谢!
答案1
经过大量进一步研究后回答了我自己的问题。
新的 udev“哲学”
显然,新的“正确”使用方式udev
是不要引发长时间运行的过程。
运行 ... 启动守护进程或其他长时间运行的进程对于 udev 来说是不适合的;分叉的进程,无论是否分离,都会在事件处理完成后被无条件地终止。
请注意,这与 OP 中的手册页引用有何矛盾。
我最好的猜测是最近的udev
变化(〜2012年的某个时候)强制所有流程包括让他们的分叉子项完成之后才允许执行继续,这是这一新哲学的执行机制。
因此,网络上所有易于访问的、以 OP 中的模式作为解决方案的文档和答案现在都被破坏了。
当您谈论设备插入时始终运行的某些守护进程时,新的长期运行模式理念是可以理解的。然而,defer
它同时也消灭了有效的用例。
解决方法
尽管如此,我还发现了一种解决方法:
/lib/udev/rules.d/98-mouse-config.rules/
SUBSYSTEM=="usb", ATTRS{idVendor}=="045e", ATTRS{idProduct}=="008c", ACTION=="add|remove", ENV{ID_TYPE}!="hid", RUN+="/home/mikeknoop/scripts/udev-receiver.sh"
udev-receiver.sh
#!/bin/bash
echo /home/mikeknoop/scripts/mouse.sh | at now
mouse.sh
#!/bin/bash
sleep 3;
export DISPLAY=":0.0"
export XAUTHORITY="/home/mikeknoop/.Xauthority"
/usr/bin/xinput --set-prop 'pointer:Microsoft Microsoft Wireless Optical Mouse® 1.0A' 'Device Accel Constant Deceleration' 2.00000
... more xinput rules here
笔记这已在 Ubuntu 13.04 上测试过并可运行
笔记您需要at
通过以下方式安装异步任务包sudo apt-get install at
我拼凑了以下解决方法:https://unix.stackexchange.com/questions/28548/how-to-run-custom-scripts-upon-usb-device-plug-in