
Вот правило из моего /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
не появится сообщение after.external.log
Это важно, потому что я пытаюсь задать некоторые свойства устройства через , xinput
но устройство не отображается в списке через , xinput list
пока не будет завершена вся udev
инициализация (пока не Done
появится after в external.log
).
Согласноudev(7) - страница руководства Linux
«Добавьте программу в список программ, которые должны быть выполнены для определенного устройства. Это можно использовать только для очень кратковременных задач. Выполнение процесса события в течение длительного периода времени может заблокировать все дальнейшие события для этого или зависимого устройства. Длительно выполняемые задачи необходимо немедленно отсоединить от самого процесса события».
Я не могу согласовать страницу руководства и поведение, которое я вижу. Может ли кто-нибудь пролить свет или предложить лучший способ установки свойств через xinput
вставку устройства?
Спасибо!
решение1
Отвечаю на свой собственный вопрос после долгих дополнительных исследований.
Новая «философия» udev
По-видимому, новый «правильный» способ использования udev
— не вызывать длительных процессов.
RUN ... Запуск демонов или других длительно работающих процессов не подходит для 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