sudo в неинтерактивном сценарии

Альтернативное решение

После окончания записи рева ответа я понял, что то, чего Вы пытаетесь достигнуть, могло быть выполнено намного более изящно с помощью xinput или даже использование конфигурации Xorg. Удостоверьтесь, что прочитали документацию об управлении устройствами ввода данных в Xorg.

Используя udev (ответ на Ваш вопрос)

Согласно моим тестам существует две проблемы с Вашими правилами:

  1. По крайней мере, на моем GNU/Linux Ubuntu 12.04, никакие проверки на ENV{DEVTYPE} когда-либо соответствие (даже при том, что этим сообщают правильно udevadm info и udevadm monitor). Это - основания, которые Вы даже не видите add подбор правила.
  2. Необходимо удалить 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"

Дополнительные соображения

Несколько вещей рассмотреть:

  1. это намного более чисто для использования ATTR{idVendor} и ATTR{idProduct} для классификации устройств. Можно безопасно измениться add правило использовать их, вместо ENV, но я оставил их как это ради простоты. В настоящее время add и remove правила почти идентичны.
  2. Рассмотрите последствия безопасности запущения скрипта как корень в каталоге, который перезаписываем другими пользователями. В Вашем особом случае это не серьезная проблема, но я не назвал бы это хорошей практикой безопасности. IMO это намного лучше поместило бы сценарий в/usr/local/bin/, делая принадлежавшим root.root и режиму 0755.
  3. Удостоверьтесь, что Вы хотите, чтобы устройство мыши принадлежало Вашему пользователю, нет действительно никакой потребности в этом, PolicyKit и Xorg должны смочь обработать корневые устройства без любых проблем.

Если Вы не должны изменять владельца устройства и Ваших работ установки с корневым устройством, то Вы могли упростить свои два правила 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 переменная.

9
22.09.2015, 23:19
5 ответов

Я думаю, что лучшее, что вы можете сделать, это запустить скрипт с помощью 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
7
27.01.2020, 20:06

Здание на мой ответ до Предварительно авторизуемое 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 и выйти иначе.

0
27.01.2020, 20:06

Добавьте свой скрипт в файл / 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

9
27.01.2020, 20:06

Вы можете использовать опцию !requiretty в sudo , а также опцию NOPASSWD . Но имейте в виду, что это снижает безопасность.

0
27.01.2020, 20:06

Будь немой. Используй много строк.

if A; then

    if sudo B ; then
        C
    fi
fi
-3
27.01.2020, 20:06

Теги

Похожие вопросы