Как заставить udev проверять аудиоустройства

Я пытаюсь написать правило udev для моего приемника Bluetooth, которое при подключении запускает сценарий, который проверяет, было ли также добавлено соответствующее аудиоустройство, и повторно подключается, если это не так. По какой-то причине, когда я включаю ресивер и он автоматически подключается, сначала аудиоустройство не добавляется. Я использую Pipewire-Pulse.

Проблема в том, что я не знаю, как заставить udev проверять аудиоустройства.pactl listне работает с правами root, но это нормально, потому что теоретическиpw-cli list-objectsдолжно сработать. Итак, мой сценарий выглядит так:

      #!/bin/bash

sleep 3

# JR-CB1 connected but not available as audio device
if bluetoothctl devices Connected | grep "25:4E:4A:C7:43:C4" && ! pw-cli list-objects | grep "25_4E_4A_C7_43_C4"; then
    # Reconnect
    bluetoothctl disconnect 25:4E:4A:C7:43:C4
    bluetoothctl connect 25:4E:4A:C7:43:C4
fi

Сsuв терминале это работает нормально. Он переподключается, если аудиоустройство отсутствует, и ничего не делает, если оно есть. Вывод после добавления аудиоустройства:

      object.path = "bluez_output.25_4E_4A_C7_43_C4.1:monitor_0"
object.path = "bluez_output.25_4E_4A_C7_43_C4.1:monitor_1"
node.name = "bluez_output.25_4E_4A_C7_43_C4.1"
device.name = "bluez_card.25_4E_4A_C7_43_C4"
object.path = "bluez_output.25_4E_4A_C7_43_C4.1:playback_1"
object.path = "bluez_output.25_4E_4A_C7_43_C4.1:playback_0"

а возвращаемое значение grep равно 0, поэтому оператор if не должен выполняться. Однако, хотя в терминале это работает, в udev по какой-то причине это не работает. При протоколировании вывода сценария, запущенного udev, выводpw-cli list-objects | grep "25_4E_4A_C7_43_C4"пусто, а возвращаемое значение равно 1, что означает, что переподключение выполнено, и я получаю бесконечный цикл переподключения.

Почему udev не может перечислить аудиоустройства Pipewire? Есть ли другой способ?

1 ответ

Думаю, я нашел решение. Как было предложено в комментарии, я рассмотрел возможность использования службы для запуска сценария. Чтобы сообщить systemd о событии устройства, я использовал следующее правило udev:

      /etc/udev/rules.d/60-bluetooth-add-event.rules

CTION=="add", SUBSYSTEM=="bluetooth", TAG+="systemd", ENV{SYSTEMD_WANTS}="bluetooth-add-event.service"

(Я пытался определить атрибут, специфичный для моего устройства Bluetooth, но без устройства Pipewire, похоже, для udev не доступны никакие уникальные атрибуты, поэтому я запускаю службу всякий раз, когда подключается какое-либо устройство bt, и позволяю сценарию обрабатывать идентификацию.)

Сервис выглядит следующим образом:

      /etc/systemd/system/bluetooth-add-event.service

[Unit]
Description=Runs when bluetooth connection is added
Requires=bluetooth.target
After=bluetooth.target

[Service]
ExecStart=/usr/bin/bluetooth-add-event.sh
Type=exec
Restart=no

[Install]
WantedBy=multi-user.target

Это не пользовательская служба, потому чтоpw-cliможет использоваться пользователем root, но не при запуске udev.

(Мое понимание опций системного модуля находится в зачаточном состоянии, поэтому любые предложения по улучшению приветствуются.)

Скрипт тот же, что и раньше:

      /usr/bin/bluetooth-add-event.sh

#!/bin/bash

sleep 3

# JR-CB1 connected but not available as audio device
if bluetoothctl devices Connected | grep "25:4E:4A:C7:43:C4" && ! pw-cli list-objects | grep "25_4E_4A_C7_43_C4"; then
    # Reconnect
    bluetoothctl disconnect 25:4E:4A:C7:43:C4
    bluetoothctl connect 25:4E:4A:C7:43:C4
fi

Теперь, когда я подключаю устройство, сценарий запускается один раз, не находит аудиоустройство, повторно подключает устройство Bluetooth, затем запускается снова, но ничего не делает, потому что находит аудиоустройство вpw-cli list-objects.

Другие вопросы по тегам