После окончания записи рева ответа я понял, что то, чего Вы пытаетесь достигнуть, могло быть выполнено намного более изящно с помощью xinput
или даже использование конфигурации Xorg. Удостоверьтесь, что прочитали документацию об управлении устройствами ввода данных в Xorg.
Согласно моим тестам существует две проблемы с Вашими правилами:
ENV{DEVTYPE}
когда-либо соответствие (даже при том, что этим сообщают правильно udevadm info
и udevadm monitor
). Это - основания, которые Вы даже не видите add
подбор правила.OWNER
присвоение от remove
правило. Это не имеет смысла, и udev игнорирует правило в целом. Попробуйте следующими двумя правилами и посмотрите, решают ли они проблему.
ACTION=="add", ENV{ID_MODEL}=="USB_Receiver", ENV{ID_VENDOR_ID}=="046d", ENV{ID_MODEL_ID}=="c51a", RUN+="/home/user/.scripts/Troubleshooting/Bugfixes/mouseswitcher_wrapper 1", OWNER="user"
ACTION=="remove", ENV{ID_MODEL}=="USB_Receiver", ENV{ID_VENDOR_ID}=="046d", ENV{ID_MODEL_ID}=="c51a", RUN+="/home/user/.scripts/Troubleshooting/Bugfixes/mouseswitcher_wrapper 0"
Несколько вещей рассмотреть:
ATTR{idVendor}
и ATTR{idProduct}
для классификации устройств. Можно безопасно измениться add
правило использовать их, вместо ENV
, но я оставил их как это ради простоты. В настоящее время add
и remove
правила почти идентичны.Если Вы не должны изменять владельца устройства и Ваших работ установки с корневым устройством, то Вы могли упростить свои два правила udev до этого:
ACTION=="add|remove", ENV{ID_MODEL}=="USB_Receiver", ENV{ID_VENDOR_ID}=="046d", ENV{ID_MODEL_ID}=="c51a", RUN+="/home/user/.scripts/Troubleshooting/Bugfixes/mouseswitcher_wrapper $env{ACTION}"
Это назовет Ваш сценарий с соответствующим действием - remove
или add
, таким образом, необходимо будет изменить сценарий для обработки этих аргументов.
Для предотвращения правила соответствовать (и сценарий для выполнения) несколько раз, необходимо сделать правило более конкретным: правило соответствует для каждого "входа" (кнопки, и т.д.) мыши. Вот почему это неоднократно выполняется. Попытайтесь добавить ENV{ID_TYPE}!="hid"
или ENV{ID_USB_DRIVER}!="*hid*"
и посмотрите, работает ли это, поскольку существует только одно устройство, которое не является HID - вершина usb_device
.
PS: Если Вы хотите сделать Ваш mouseswitcher
более гибкий сценарий, и выполняет систему с ConsoleKit, Вы могли использовать ck-list-sessions
получить пользователя, который в настоящее время зарегистрирован и использует ту информацию для установки XAUTHORITY
переменная.
Я думаю, что лучшее, что вы можете сделать, это запустить скрипт с помощью Sudo
, а затем запустите процессы, которые вы хотите запускать как Нормальный пользователь явно с Su
или или
User Sudo
:
#!/usr/bin/env bash
## Detect the user who launched the script
usr=$(env | grep SUDO_USER | cut -d= -f 2)
## Exit if the script was not launched by root or through sudo
if [ -z $usr ] && [ $USER = "root" ]
then
echo "The script needs to run as root" && exit 1
fi
## Run the job(s) that don't need root
sudo -u $usr commandA
## Run the job that needs to be run as root
commandB
Здание на мой ответ до Предварительно авторизуемое sudo? (Так можно запускать позже) , Напишите два скрипта:
ABC_Script
:
#! / Bin / Sh
sudo -b ./b_script
A &&> A_IS_DONE
пока [ ! -f b_is_done]
делать
Спать 60.
Готово
RM -F B_IS_DONE.
Слияние
B_Script
:
#! / Bin / sh
пока [ ! -f a_is_done]
делать
Спать 60.
Готово
RM -F a_is_done.
B &&> B_IS_DONE
Бег ./ abc_script
:
sudo -b ./b_script
.
Это спрашивает пароль ( немедленно после запуска ABC_Script
).
Предполагая, что правильный пароль введен,
Это порождает B_Script
в b b aCkground (поскольку --b
был указан) в качестве корня.
Похоже, это эквивалентно sudo sh -c "./b_script &"
. B_Script
начинает бежать асинхронно, параллельно с ABC_Script
.
B_Script
Испытания на существование файла под названием A_IS_DONE
и петли, пока не появится. abc_script
работает A
.
Если / когда успешно завершится
, скрипт создает файл под названием A_IS_DONE
. ABC_Script
Затем тесты на существование файла под названием B_IS_DONE
и петли, пока не появится. B_Script
обнаруживает существование A_IS_DONE
и вырывается из цикла.
Удаляет файл A_IS_DONE
A_IS_DONE B
.
Помните, B_Script
работает как root, поэтому он работает b
в качестве корня.
Если / когда B
успешно заканчивается,
Сценарий создает файл под названием B_IS_DONE
и выходы. ABC_Script
обнаруживает существование b_is_done
и вырывается из цикла.
Удаляет файл b_IS_DONE
.
Помните, B_Script
RAN как root, поэтому B_IS_DONE
принадлежит root,
И вы хотите использовать RM -F
, чтобы не получить запрос на подтверждение.
ABC_Script
затем работает C
и выходы. Примечания для дальнейшей доработки:
ABC_Script
, вероятно, должен работать b_Script
абсолютным путем, а не . /
. A_IS_DONE
и B_IS_DONE
,
ABC_Script
, вероятно, должен генерировать случайные, уникальные имена файлов. Необходимо быть положение для скрипта, который является спиновым ожиданием
Быть уведомленным, если программа, которую она ждет, закончила, но не удалось.
(Прямо сейчас, если не удается
A , оба сценария просто попадают в бесконечный петлю ожидания.)
Это может быть так же просто, как изменение
A &&> A_IS_DONE
к
; echo $? > A_is_done.
, а затем изменение спина - ждет, чтобы прочитать x _is_done
файлов,
и продолжить, если он содержит 0 и выйти иначе.
Добавьте свой скрипт в файл / etc / sudoers
с атрибутом NOPASSWD
, чтобы оно было разрешено запустить без запроса пароля. Вы можете связать это до конкретного пользователя (или набора пользователей) или позволить ему работать с Sudo
кем-либо в вашей системе.
Строка образца для сценария под названием / usr / local / bin / bossy
может выглядеть что-то вроде этого
ALL ALL = (root) NOPASSWD: /usr/local/bin/bossy
, и вы тогда использовали что-то подобное
A && sudo bossy && C
для этого примера Путь
включает / usr / local / bin
. Если нет, то просто используйте полный путь к скрипту, т.е. Sudo / usr / local / bin / bossy
Вы можете использовать опцию !requiretty
в sudo
, а также опцию NOPASSWD
. Но имейте в виду, что это снижает безопасность.