Запуск bash-скрипта из правила udev

Вопрос или проблема

Я прочитал другие похожие вопросы, но ответы там не работают в моем случае. У меня есть правило udev в файле /etc/udev/rules.d/99-headset_switcher.rules Правило следующее:

ACTION=="add", RUN="/usr/local/bin/switch_headset.sh"

Когда я запускаю udevadm test /sys/class/bluetooth/hci0, я вижу:

DEVPATH=/devices/pci0000:00/0000:00:08.1/0000:04:00.4/usb3/3-1/3-1:1.0/bluetooth/hci0
DEVTYPE=host
ACTION=add
SUBSYSTEM=bluetooth
TAGS=:systemd:
CURRENT_TAGS=:systemd:
SYSTEMD_ALIAS=/sys/subsystem/bluetooth/devices/hci0
SYSTEMD_WANTS=bluetooth.target
SYSTEMD_USER_WANTS=bluetooth.target
USEC_INITIALIZED=9792645
run: '/usr/local/bin/switch_headset.sh'
Unload module index
Unloaded link configuration context.

Что указывает на то, что мой скрипт запускается. Скрипт содержит:

cat /usr/local/bin/switch_headset.sh                                                                                                                                                                                                                                                                                                                                                   
#!/bin/bash
/usr/bin/echo переключение гарнитуры >>/tmp/headset.log

Тест udev не добавляет ничего в файл лога. Если я запускаю файл в оболочке, все работает нормально.

Вот что я попробовал до сих пор.

  1. Изменил все пути на абсолютные.
  2. Пробовал RUN+= и RUN=.
  3. Удалил все из моего правила и поэтапно строил его с RUN…, ничего не сработало.
  4. Я знаю, что правила udev работают очень короткое время, но не думаю, что это проблема здесь.

Буду рад любым подсказкам, чего я упускаю.

Ответ или решение

Запуск Bash-скрипта из правила udev может быть сложной задачей, и справедливо, что у вас возникают трудности. Важно знать, что окружение, в котором выполняются правила udev, значительно отличается от обычной командной оболочки. Давайте разберемся, как правильно настроить вашу udev-правило для запуска скрипта.

Проблема

Ваше правило udev, которое находится в файле /etc/udev/rules.d/99-headset_switcher.rules, выглядит следующим образом:

ACTION=="add", RUN="/usr/local/bin/switch_headset.sh"

Вы упомянули, что ваш скрипт не записывает данные в файл /tmp/headset.log, когда udev запускает его, хотя при ручном запуске все проходит корректно.

Причины и решение

  1. Ограниченные переменные среды: Скрипты, выполняемые через udev, не имеют доступа к той же переменной среды, что и обычные сессии оболочки. Это значит, что некоторые команды или пути могут не работать.

  2. Проблемы с правами: Хотя сам udev запускается с правами root, следует убедиться, что пользователь, под которым записывается файл, имеет соответствующие разрешения на запись в /tmp/headset.log.

  3. Логи и диагностика: Чтобы упростить диагностику, необходимо добавить больше логирования в ваш скрипт. Отредактируйте ваш файл switch_headset.sh, чтобы записывать сообщения об ошибках:

    #!/bin/bash
    echo "$(date): switching headset" >> /tmp/headset.log 2>&1
  4. Echo вместо /usr/bin/echo: В вашем скрипте, верно использование echo, но убедитесь, что вы используете его корректно. Явное указание пути может быть не обязательным.

  5. Использование udevadm control: После изменения правил udev, возможно, вам понадобится перезагрузить daemon:

    sudo udevadm control --reload-rules
    sudo udevadm trigger

Альтернативные подходы

Если все вышеупомянутое не помогло, вы можете попробовать следующие альтернативные пути:

  • Запуск через другой механизм: Вместо RUN вы можете использовать PROGRAM, чтобы запустить ваш скрипт через интерпретатор.

    ACTION=="add", PROGRAM="/usr/local/bin/switch_headset.sh"
  • Использование systemd: Если ваша система поддерживает systemd, вы можете рассмотреть возможность создания systemd-сервиса, который будет зависеть от события udev. Это поможет избежать ограничений, связанных с запуском через udev.

Подведение итогов

Запуск скриптов через udev требует понимания специфики окружения, в котором выполняются правила. Путем тщательной настройки и добавления логирования можно диагностировать проблемы и обеспечить успешное выполнение скриптов. Используйте приведенные стратегии для выявления и устранения возможных проблем, и вы сможете решить свою задачу более эффективно.

Оцените материал
Добавить комментарий

Капча загружается...