Notification des changements sur un fichier sous / proc

13

J'ai écrit un petit `` démon '' en bash qui passera aux écouteurs s'ils sont détectés, et sinon, passer à un haut-parleur USB externe avec PulseAudio.

Ce que je recherche, c'est un moyen d'obtenir une notification des modifications sur le fichier /proc/asound/card0/codec#0, tout comme inotifywaitles vrais fichiers (en considérant les fichiers sous / proc comme des "pseudo-fichiers").

Je trouve mon code un peu fou, car il fonctionne sleep 1avec awktoute la journée, soit 86400 fois par jour :)

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

Ce que je recherche, c'est quelque chose comme (cet exemple ne fonctionne pas):

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

De cette façon, les commandes à l'intérieur de la boucle ne seraient exécutées que lorsqu'il y aurait de réels changements dans le $codecfichier.

Teresa e Junior
la source
1
Ce n'est pas fou - des choses comme topet les moniteurs de système GUI lisent beaucoup plus que cela /procà de courts intervalles. Bien sûr, ils le font probablement beaucoup plus efficacement en tant qu'exécutables compilés, mais le fait est que: rechercher des informations est une tâche courante.
goldilocks
2
Étant donné que le problème sous-jacent n'est pas unique à vous, je m'attendrais à ce qu'il y ait une solution prête à l'emploi (au moins pour certains matériels) - jetez un œil à unix.stackexchange.com/questions/25776/… et superuser.com/questions / 339900 /… . La source ultime est bien sûr l'arborescence du noyau (et les spécifications matérielles si vous décidez de l'implémenter dans un pilote).
peterph
1
Si cela apparaît dans /proc, vous pouvez probablement déclencher votre script avec une règle udev , ce qui serait plutôt idéal. Moins idéal est à quel point il peut être fastidieux d'élaborer des règles udev;)
goldilocks
@peterph D'après ce que j'ai pu recueillir, hda-verb fournit une interface pour définir ou vérifier les paramètres, mais il semble que je devrais également l'exécuter toutes les secondes.
Teresa e Junior
@goldilocks Brancher les écouteurs n'envoie aucun événement udev. Ou est-ce qu'il me manque quelque chose de plus?
Teresa e Junior

Réponses:

10

Ce que je recherche, c'est un moyen d'obtenir une notification des modifications sur le fichier [en proc]

Vous ne pouvez pas, car ce ne sont pas des fichiers. Ce n'est pas tout à fait une question en double, mais la réponse ici explique pourquoi.

/procest une interface noyau. Il n'y a pas de vrais fichiers là-bas, donc ils ne peuvent pas changer. La lecture à partir des poignées est une demande et les données du fichier lorsque vous le lisez sont une réponse à cela.

La seule façon de simuler quelque chose comme ça serait de lire le fichier à intervalles et de comparer le contenu pour voir si la réponse du noyau a changé - on dirait que vous l'avez déjà fait.

Si vous statprocfs des fichiers, atime et mtime seront les mêmes: pour certains fichiers, c'est à chaque fois que l'appel stat a été, pour d'autres à un moment donné lors du démarrage du système. Dans le premier cas, il semblera toujours avoir changé, dans le second, il ne semblera jamais avoir changé.

boucle d'or
la source
Malheureusement, même l'interroger toutes les secondes ajoute une latence considérable (par exemple 500 ms). J'espérais qu'il y aurait un moyen plus rapide / plus efficace de le faire, mais puisque vous avez mentionné que des applications comme top le faisaient de la même manière, je pense que je vais le laisser de cette façon.
Teresa e Junior
@TeresaeJunior Si la latence est un problème (je pense qu'elle n'est pas là), par exemple, parce que la durée du sondage est utilisée dans un calcul, vous chronométrez la durée réelle (et pas seulement utilisez le temps que vous avez demandé à dormir) . Cela semble cependant beaucoup; Je n'ai jamais profilé de scripts bash, donc je ne sais pas ce qui serait normal ici (hmm ... bonne question séparée). Invoquer awk == fork()et des trucs comme ça coûte cher; les utilitaires écrits tout en C auraient, comme mentionné, des méthodes plus rapides. Je ne pense toujours pas que vous ajoutiez beaucoup de charge au système global.
goldilocks
1
Non, désolé, je voulais dire: depuis le moment où je branche les écouteurs jusqu'au prochain sommeil, il y a un certain retard notable. Mais je ne prévois pas de diminuer le temps de sommeil. Merci de votre aide!
Teresa e Junior
4

Si vous utilisez PulseAudio, procédez comme pactl subscribesuit.

user66233
la source
Oui en effet! J'ai commencé à l'utiliser après avoir compilé PA 4.0 il y a quelques mois à cause de quelques problèmes audio. La version sur Debian Stable est 2.0 (bien qu'ils aient récemment téléchargé 4.0 sur les rétroportages), et il n'y en avait pas subscribesur 2.0.
Teresa e Junior
2

Gardez également à l'esprit que certains fichiers sous /proc/permettent d'être surveillés pour les modifications via l'interrogation, par exemple si vous le faites, man procvous pouvez lire ce qui suit sur le /proc/self/mountsfichier:

/ proc / [pid] / mounts (depuis Linux 2.4.19) Ce fichier répertorie tous les systèmes de fichiers actuellement montés dans l'espace de noms de montage du processus (voir mount_namespaces (7)). Le format de ce fichier est documenté dans fstab (5).

Depuis la version 2.6.15 du noyau, ce fichier est interrogeable: après ouverture du fichier en lecture, une modification de ce fichier (c'est-à-dire un montage ou un démontage du système de fichiers) fait que select (2) marque le descripteur de fichier comme ayant une condition exceptionnelle, et poll (2) et epoll_wait (2) marquent le fichier comme ayant un événement prioritaire (POLLPRI). (Avant Linux 2.6.30, une modification de ce fichier était indiquée par le descripteur de fichier marqué comme lisible pour select (2) et marqué comme ayant une condition d'erreur pour poll (2) et epoll_wait (2).)

Et c'est exactement ce qui est mis en œuvre dans la question suivante:

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

Nelson
la source
-1

Essayez d'utiliser netlinkpour surveiller les /procfichiers modifiés.

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

meyao
la source
Bienvenue sur le site. Veuillez ajouter quelques explications sur la façon d’utiliser netlinkpour réaliser cette tâche; cela ne ressort pas du contenu externe que vous avez lié. En outre, il est généralement préférable de ne pas avoir de réponses "lien uniquement" car le contenu externe peut changer ou être supprimé (voir l'avis en haut de votre page initialement liée, par exemple), ce qui nuirait à l'utilité de votre contribution.
AdminBee