Kernel-Nachrichten an einen anderen Prozess weiterleiten, wenn sie auftreten

1143
TuxRug

Auf meinem Laptop befindet sich ein OLED-Bildschirm, der für die Anzeige von Statusinformationen konfiguriert ist. Der aktuelle Treiber, den ich in Linux installiert habe, kann Meldungen anzeigen, indem er sie als Argument durch Leerzeichen an ein Skript sendet.

Beispiel: Der Befehl /opt/asusg50oled/utils/notify.sh Hi Everybody "Hello World"wird auf dem oled-Bildschirm angezeigt:

Hi Everybody Hello World 

Wenn eine andere Nachricht gesendet wird, bevor die alte verschwindet, und die Statusinformationen wiederhergestellt werden, wird die oberste Nachricht verworfen. Beispiel: weniger als 30 Sekunden nach dem vorherigen Beispiel /opt/asusg50oled/utils/notify.sh "Bananas have potassium"wird ausgeführt:

Everybody Hello World Bananas have potassium 

Ich möchte Kernel-Nachrichten (die Art, die Sie beim Ausführen sehen dmesg) an dieses Skript weiterleiten. Wenn ich zum Beispiel ein USB-Laufwerk stecke, werden folgende Informationen auf dem OLED-Bildschirm angezeigt, wenn sie protokolliert werden:

[ 1283.200150] usb 2-4: new high speed USB device using ehci_hcd and address 4 [ 1283.353322] scsi9 : usb-storage 2-4:1.0 [ 1284.351366] scsi 9:0:0:0: Direct-Access SanDisk Cruzer 1.03 PQ: 0 ANSI: 2 [ 1284.352697] sd 9:0:0:0: Attached scsi generic sg4 type 0 [ 1284.355669] sd 9:0:0:0: [sdd] 31266816 512-byte logical blocks: (16.0 GB/14.9 GiB) [ 1284.357032] sd 9:0:0:0: [sdd] Write Protect is off [ 1284.357041] sd 9:0:0:0: [sdd] Mode Sense: 03 00 00 00 [ 1284.357047] sd 9:0:0:0: [sdd] Assuming drive cache: write through [ 1284.364356] sd 9:0:0:0: [sdd] Assuming drive cache: write through [ 1284.364371] sdd: sdd1 [ 1284.371656] sd 9:0:0:0: [sdd] Assuming drive cache: write through [ 1284.371666] sd 9:0:0:0: [sdd] Attached SCSI removable disk 

Beachten Sie, dass angesichts der begrenzten Breite des Bildschirms auch das Entfernen der Zeitstempel nützlich sein könnte. Am Ende der Protokollierung würde der Bildschirm etwa 30 Sekunden lang angezeigt:

 sdd: sdd1 sd 9:0:0:0: [sdd] Assuming drive cache: write through sd 9:0:0:0: [sdd] Attached SCSI removable disk 

Zur Verdeutlichung möchte ich, dass Kernel-Nachrichten durch Ausführung live gesendet werden /opt/asusg50oled/utils/notify.sh "$MESSAGE"

Ich kann Filter einsetzen, um alles auszusondern, was ich später nicht sehen möchte. Ich möchte nur wissen, wie die oben genannten Teile zu tun sind. Wie kann ich das machen?

Bearbeiten

Wie Ciclamino vorschlug, habe ich meiner /etc/rsyslog.conf -Datei die folgende Zeile hinzugefügt:

kern.* ^/opt/asusg50oled/utils/notify.sh 

Das funktionierte fast, aber die Formatierung führte dazu, dass die OLED nur das Datum, den Hostnamen und das Wort "Kernel" zeigte, bevor der Speicherplatz überschritten wurde. Nach ein wenig Graben habe ich folgendes herausgefunden:

$template OLEDformat,"%msg%0 kern.* ^/opt/asusg50oled/utils/notify.sh;OLEDformat 

Das ist fast da, aber ich renne wegen Zeitstempel aus dem Raum. Beispieldarstellung:

[ 4477.993774] sd 11:0:0:0: [sdb] At 

Ich möchte die eingeklammerten Zahlen loswerden, also bleibe ich bei

sd 11:0:0:0: [sdb] Attached SCSI rem 

Immer noch nicht perfekt, aber das Beste, was ich mit der Größe des Bildschirms bekomme. Es wäre sogar noch besser, wenn das Zeichen auf 36 Zeichen aufgeteilt würde, sodass ich etwa Folgendes haben kann:

sd 11:0:0:0: [sdb] Attached SCSI rem ovable disk 

Gelöst

Ich akzeptiere Ciclaminos Antwort, da sie mich dahin brachte, wo ich sein musste. Folgendes habe ich am Ende getan:

Ich erstellt und hinzugefügt Bit ausführen, um Shell - Skript /opt/asusg50oled/utils/notify-kern.shenthält

#!/bin/bash cd `dirname $0` stringA=$1 stringB=$ stringC=$ stringD=$ ./notify.sh "$stringC" "$stringD" 

Dann habe ich an /etc/rsyslog.conf angehängt

## output kernel messages to OLED $template OLEDformat,"%msg%" kern.* ^/opt/asusg50oled/utils/notify-kern.sh;OLEDformat 

Schließlich habe ich rsyslog mit neu gestartet sudo service rsyslog restart.

4

3 Antworten auf die Frage

3
lesmana

Hier ist eine schnelle und schmutzige Lösung:

tail -n 0 -f /var/log/messages | while read -r MESSAGE; do /opt/asusg50oled/utils/notify.sh "$MESSAGE" done 
Dies treibt sie jedoch nicht an, wenn sie passieren, und ich möchte nur die, die gerade geschossen haben, um sie anzuzeigen. Ich möchte etwas, das die Nachrichten erfasst, wenn sie produziert werden. TuxRug vor 13 Jahren 0
@TuxRug Ich habe versaut. Es hätte `/ var / log / messages` anstelle von` / var / log / dmesg` sein sollen. Ich habe meine Antwort aktualisiert. Mit "tail -n 0" erhalten Sie nur die neuesten Meldungen nach Aufruf des Befehls. lesmana vor 13 Jahren 1
3
Ciclamino

Sie können syslog verwenden, um Kernel-Nachrichten abzufangen und an einen Befehl weiterzuleiten. Die Syntax wird für die verschiedenen Implementierungen von syslogd etwas unterschiedlich sein. Hier ist ein Beispiel, wie man dies mit rsyslog (in /etc/rsyslog.conf) macht:

kern.* ^/opt/asusg50oled/utils/notify.sh 
Das sieht genau so aus, wie ich es machen möchte. Ich werde prüfen, ob es das nächste Mal, wenn ich in Linux bin, richtig funktioniert. TuxRug vor 13 Jahren 0
Das ist SEHR in der Nähe ... Im Moment bekomme ich das Datum, den Hostnamen, den Wortkern, einen Doppelpunkt und dann die OLED-Speicherkapazität leer ... Ich werde sehen, ob ich herausfinden kann, wie ich das abschneiden kann Ich bin mir sicher, dass ich ein Zwischenskript schreiben kann, um das: und alles davor herauszuholen. TuxRug vor 13 Jahren 0
Anscheinend brauche ich etwas mehr Hilfe ... wie bekomme ich es, alles bis auf das erste ':' abzurasieren? Im Moment bekomme ich: 14. April 11:36:35 TuxTop-III-LM-Kernel: `und dann geht mir der Platz aus. TuxRug vor 13 Jahren 0
Ok, ich habe etwas gefunden, das mich noch näher gebracht hat ... Ich habe eine Vorlage verwendet (siehe Änderungen an der Frage) .. Immer noch nicht ganz da. TuxRug vor 13 Jahren 0
0
new123456

Sie können die Ausgabe der /proc/kmsgverwendeten tailMethode oder der von Ihnen bevorzugten Methode wiederholt lesen .

Ich denke jedoch, dass Sie dazu root sein müssen.

Unglücklicherweise würden dadurch die Nachrichten unendlich oft ausgedruckt. Ich möchte, dass der Befehl einmal pro Nachricht ausgelöst wird, sodass die Nachricht 30 Sekunden lang angezeigt wird. Wenn nach 30 Sekunden keine neue Nachricht vergangen ist, wird wieder die normale Statusanzeige angezeigt. TuxRug vor 13 Jahren 0