Benachrichtigung über Änderungen an einer Datei unter / proc

13

Ich habe einen kleinen 'Daemon' in Bash geschrieben, der auf die Kopfhörer umschaltet, wenn sie erkannt werden, und wenn nicht, auf einen externen USB-Lautsprecher mit PulseAudio umschaltet.

Was ich suche, ist eine Möglichkeit, Benachrichtigungen über Änderungen an der Datei zu erhalten /proc/asound/card0/codec#0, wie inotifywaitdies auch bei echten Dateien der Fall ist (Dateien unter / proc werden als "Pseudodateien" betrachtet).

Ich finde meinen Code ein bisschen verrückt, denn es läuft sleep 1mit awkfür den ganzen Tag, die 86.400 mal pro Tag ist :)

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

Was ich suche, ist etwas wie (dieses Beispiel funktioniert nicht):

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

Auf diese Weise werden die Befehle in der Schleife nur ausgeführt, wenn die $codecDatei tatsächlich geändert wurde .

Teresa und Junior
quelle
1
Es ist nicht verrückt - Dinge wie topund GUI-Systemmonitore lesen /procin kurzen Intervallen viel mehr als das . Natürlich machen sie es wahrscheinlich viel effizienter als kompilierte ausführbare Dateien, aber der Punkt ist: Das Abrufen von Informationen ist eine häufige Aufgabe.
Goldlöckchen
2
Da das zugrunde liegende Problem zu Ihnen nicht eindeutig zuzuordnen ist, würde ich es erwarten einige fertige Lösung zu sein (zumindest für einige Hardware) - haben einen Blick auf unix.stackexchange.com/questions/25776/... und superuser.com/questions / 339900 /… . Die ultimative Quelle ist natürlich der Kernelbaum (und die Hardwarespezifikationen, falls Sie sich dafür entscheiden, ihn in einen Treiber zu implementieren).
Peterph
1
Wenn dies in auftaucht /proc, können Sie Ihr Skript wahrscheinlich mit einer udev- Regel auslösen , was ziemlich ideal wäre. Weniger ideal ist, wie mühsam es sein kann, mit udev-Regeln zu kommen;)
Goldlöckchen
@peterph Soweit ich das beurteilen kann, bietet hda-verb eine Schnittstelle zum Einstellen oder Überprüfen von Parametern, aber es sieht so aus, als müsste ich es auch jede Sekunde ausführen.
Teresa e Junior
@goldilocks Beim Anschließen der Kopfhörer wird kein udev-Ereignis gesendet. Oder fehlt mir noch etwas?
Teresa e Junior

Antworten:

10

Was ich suche, ist eine Möglichkeit, Benachrichtigungen über Änderungen an der Datei zu erhalten [in proc]

Sie können nicht, weil sie keine Dateien sind. Dies ist keine doppelte Frage, aber die Antwort hier erklärt, warum.

/procist eine Kernel-Schnittstelle. Es gibt dort keine echten Dateien, daher können sie sich nicht ändern. Das Lesen aus den Handles ist eine Anforderung, und die Daten in der Datei, wenn Sie sie lesen, sind eine Antwort darauf.

Die einzige Möglichkeit, so etwas zu simulieren, besteht darin, die Datei in regelmäßigen Abständen zu lesen und den Inhalt zu vergleichen, um festzustellen, ob sich die Antwort des Kernels geändert hat.

Wenn Sie statDateien verarbeiten, stimmen atime und mtime überein: Bei einigen Dateien handelt es sich um den Zeitpunkt des stat-Aufrufs, bei anderen um einen Zeitraum ab dem Systemstart. Im ersten Fall wird es immer anders zu sein scheinen, im zweiten Fall wird es nie anders zu sein scheinen.

Goldlöckchen
quelle
Leider führt selbst das Abfragen pro Sekunde zu einer beträchtlichen Latenz (z. B. 500 ms). Ich hatte gehofft, dass es eine schnellere / effizientere Möglichkeit gibt, aber da Sie erwähnt haben, dass Apps wie top es genauso machen, werde ich es so belassen.
Teresa e Junior
@TeresaeJunior Wenn die Latenz ein Problem ist (ich denke, es ist nicht hier), z. B. weil die Dauer der Umfrage in einer Berechnung verwendet wird, würden Sie die tatsächliche Dauer zeitlich festlegen (und nicht nur die Zeit verwenden, die Sie zum Schlafen gebeten haben) . Das scheint aber viel zu sein; Ich habe noch nie ein Profil für Bash-Skripte erstellt, daher weiß ich nicht, was hier normal wäre (hmm ... gute separate Frage). Awk == aufzurufen fork()und solche Sachen sind teuer; Dienstprogramme, die alle in C geschrieben wurden, hätten, wie erwähnt, schnellere Methoden. Ich glaube immer noch nicht, dass Sie dem System insgesamt viel Last hinzufügen.
Goldlöckchen
1
Nein, tut mir leid, ich meinte eigentlich: Vom Anschließen der Kopfhörer bis zum nächsten Schlaf gibt es eine merkliche Verzögerung. Aber ich habe nicht vor, die Schlafzeit zu verkürzen. Danke für Ihre Hilfe!
Teresa e Junior
4

Wenn Sie PulseAudio verwenden, pactl subscribegeschieht dies.

user66233
quelle
Ja in der Tat! Ich habe es nach dem Kompilieren von PA 4.0 vor einigen Monaten aufgrund von Audioproblemen verwendet. Die Version auf Debian Stable ist 2.0 (obwohl sie vor kurzem 4.0 in die Backports hochgeladen haben), und es gab keine Version subscribeauf 2.0.
Teresa e Junior
2

Bedenken Sie auch, dass einige Dateien /proc/, für die eine Überwachung auf Änderungen per Abruf zulässig ist, z. B. wenn Sie dies tun man proc, Folgendes über /proc/self/mountsDateien lesen können :

/ proc / [pid] / mounts (seit Linux 2.4.19) Diese Datei listet alle Dateisysteme auf, die derzeit im Mount-Namespace des Prozesses gemountet sind (siehe mount_namespaces (7)). Das Format dieser Datei ist in fstab (5) dokumentiert.

Seit der Kernel-Version 2.6.15 ist diese Datei abrufbar: Nach dem Öffnen der Datei zum Lesen führt eine Änderung in dieser Datei (dh das Ein- oder Aushängen des Dateisystems) dazu, dass select (2) den Dateideskriptor als außergewöhnlich markiert und poll (2) und epoll_wait (2) kennzeichnen die Datei mit einem Prioritätsereignis (POLLPRI). (Vor Linux 2.6.30 wurde eine Änderung in dieser Datei angezeigt, indem der Dateideskriptor für select (2) als lesbar und für poll (2) und epoll_wait (2) als fehlerhaft markiert wurde.)

Und genau das wird in der folgenden Frage umgesetzt:

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

Nelson
quelle