Уведомлять об изменениях в файле в / proc

13

Я написал небольшой «демон» в bash, который переключится на наушники, если они обнаружены, а если нет, переключится на внешний USB-динамик с помощью PulseAudio.

То, что я ищу, - это какой-то способ получать уведомления об изменениях в файле /proc/asound/card0/codec#0, так же как inotifywaitи в реальных файлах (рассматривая файлы в / proc как «псевдофайлы»).

Я нахожу мой код немного безумные, потому что он работает sleep 1с в awkтечение всего дня, то есть 86400 раз в день :)

while sleep 1; do
    _1=${_2:-}
    _2=$(awk '/Pin-ctls/{n++;if(n==4)print}' '/proc/asound/card0/codec#0')

    [[ ${_1:-} = $_2 ]] ||
        if [[ $_2 =~ OUT ]]; then
            use_speakers
        else
            use_internal
        fi
done

Я ищу что-то вроде (этот пример не работает):

codec=/proc/asound/card0/codec#0
while inotifywait $codec; do
    if [[ $(awk '/Pin-ctls/{n++;if(n==4)print}' $codec) =~ OUT ]]; then
        use_speakers
    else
        use_internal
    fi
done

Таким образом, команды внутри цикла будут выполняться только при наличии реальных изменений в $codecфайле.

Тереза ​​и Джуниор
источник
1
Это не безумие - подобные вещи topи системные мониторы с графическим интерфейсом читают намного больше, чем /procза короткие промежутки времени. Конечно, они, вероятно, делают это гораздо более эффективно, чем скомпилированные исполняемые файлы, но суть в том, что опрос информации является обычной задачей.
Златовласка
2
Поскольку основная проблема не является уникальной для вас, я ожидаю, что будет какое-то готовое решение (по крайней мере для некоторого оборудования) - взгляните на unix.stackexchange.com/questions/25776/… и superuser.com/questions / 339900 /… . Окончательный источник - это, конечно, дерево ядра (и технические характеристики оборудования, если вы решите внедрить его в какой-то драйвер).
Петер
1
Если это проявляется в /proc, вы, вероятно, можете запустить свой сценарий с помощью правила udev , что было бы довольно идеально. Менее идеальным является то, насколько скучно придумывать правила udev;)
Златовласка,
@peterph Из того, что я мог собрать, hda-verb предоставляет интерфейс для установки или проверки параметров, но, похоже, мне придется запускать его и каждую секунду.
Тереза ​​и Джуниор
@goldilocks Подключение наушников не отправляет ни одного события udev. Или что-то еще мне не хватает?
Teresa e Junior

Ответы:

10

То, что я ищу, это какой-то способ получить уведомление об изменениях в файле [в proc]

Вы не можете, потому что они не файлы. Это не совсем дублирующий вопрос, но ответ здесь объясняет почему.

/procинтерфейс ядра Там нет реальных файлов, поэтому они не могут измениться. Чтение из дескрипторов - это запрос, а данные в файле, когда вы читаете его, являются ответом на это.

Единственный способ, которым вы могли бы смоделировать что-то подобное, это прочитать файл через определенные промежутки времени и сравнить содержимое, чтобы увидеть, изменился ли ответ от ядра - похоже, вы уже сделали это.

Если вы statprocfs файлы, atime и mtime будут одинаковыми: для некоторых файлов это всегда, когда был вызов stat, для других - время во время загрузки системы. В первом случае, кажется, что он всегда изменился, во втором - никогда не изменится.

лютик золотистый
источник
К сожалению, даже опрос его каждую секунду добавляет значительную задержку (например, 500 мс). Я надеялся, что будет более быстрый / более эффективный способ сделать это, но, поскольку вы упомянули, что приложения типа top делают это так же, я думаю, что я оставлю это таким образом.
Тереза ​​и Юниор
@TeresaeJunior Если задержка является проблемой (я думаю, что ее здесь нет), например, потому что длительность опроса используется в расчете, вы бы рассчитали фактическую продолжительность (а не просто использовали время, которое вы просили заснуть) , Это кажется очень много, хотя; Я никогда не профилировал скрипты bash, поэтому я не знаю, что здесь будет нормально (хм ... хороший отдельный вопрос). Вызов awk == fork()и тому подобное стоит дорого; Как уже упоминалось, утилиты, написанные на языке C, будут иметь более быстрые методы. Я все еще не думаю, что вы увеличиваете нагрузку на систему в целом.
Златовласка
1
Нет, извините, я действительно имел в виду: с момента подключения наушников до следующего сна происходит заметная задержка. Но я не планирую сокращать время сна. Спасибо за вашу помощь!
Тереза ​​и Джуниор
4

Если вы используете PulseAudio, сделайте pactl subscribeэто.

user66233
источник
Да, в самом деле! Я начал использовать его после компиляции PA 4.0 несколько месяцев назад из-за некоторых проблем со звуком. Версия в Debian Stable - 2.0 (хотя недавно они загрузили 4.0 в бэкпорт), а subscribeв 2.0 не было.
Тереза ​​и Джуниор
2

Также имейте в виду, что некоторые файлы, для которых /proc/разрешено отслеживание изменений с помощью опроса, например, если вы это man procсделаете, можете прочитать о /proc/self/mountsфайле следующее :

/ proc / [pid] / mounts (начиная с Linux 2.4.19) В этом файле перечислены все файловые системы, которые в настоящий момент смонтированы в пространстве имен монтирования процесса (см. mount_namespaces (7)). Формат этого файла задокументирован в fstab (5).

Начиная с версии ядра 2.6.15, этот файл доступен для опроса: после открытия файла для чтения изменение в этом файле (т. Е. Монтирование или размонтирование файловой системы) заставляет select (2) пометить дескриптор файла как имеющий исключительное условие, и poll (2) и epoll_wait (2) помечают файл как имеющий приоритетное событие (POLLPRI). (До Linux 2.6.30 изменение в этом файле указывалось на то, что дескриптор файла был помечен как читаемый для select (2) и помечен как имеющий условие ошибки для poll (2) и epoll_wait (2).)

И это именно то, что реализуется в следующем вопросе:

/programming/5070801/monitoring-mount-point-changes-via-proc-mounts

нельсон
источник
-1

Попробуйте использовать netlinkдля мониторинга /procизмененных файлов.

https://mdlayher.com/blog/linux-netlink-and-go-part-1-netlink/

meyao
источник
Добро пожаловать на сайт. Пожалуйста, добавьте некоторые объяснения о том, как использовать netlinkдля достижения этой задачи; это не видно из внешнего контента, на который вы ссылаетесь. Кроме того, в общем случае предпочтительнее не иметь ответов «только для ссылок», поскольку внешний контент может измениться или быть удален (см., Например, уведомление в верхней части вашей изначально связанной страницы), что уменьшит полезность вашего вклада.
AdminBee