In diesem Artikel zeige ich, wie der udev-Daemon eines Linux Betriebssystems verwendet werden kann. Der udev-Daemon ist auf vielen Linuxdistributionen aktiv und kann daher auch z. B. auf einem Desktop PC mit einem Betriebssystem wie Ubuntu benutzt werden.
Was ist der udev-Daemon?:
Der udev-Daemon (oder auch udev-Dienst) ist ein Hintergrundprogramm, welches die Gerätedateien im Verzeichnis /dev
verwaltet. Dieser Dienst verwendet verschiedene Regeln, die festlegen wie sich der Dienst bei einer bestimmten Aktion verhalten soll.
Ein praktisches Beispiel für die Verwendung des udev-Daemons sind USB-Sticks, da diese unter Linux immer erst gemountet werden müssen, bevor sie verwendet werden können. Mit Hilfe des udev-Daemon kann dieser Prozess automatisiert werden, um so einen Stick mit einer bestimmten Bezeichnung automatisch an eine bestimmte Stelle zu mounten. Weiterhin ist es möglich, dass der udev-Daemon ein bestimmtes Shellskript beim Einstecken eines USB-Sticks auszuführen um so z. B. Dateien automatisch auf den USB-Stick zu kopieren.
Eine eigene Regel erstellen:
Das Ziel soll es sein eine Regel zu erstellen, welche in einer Log-Datei festhält, wann ein USB-Stick an das Raspberry Pi angesteckt worden ist. Für die Umsetzung dieser Idee werden zwei Komponenten benötigt:
- Die udev-Regel
- Ein Shellskript zum erstellen der Logdatei
Die udev-Regeln werden im Verzeichnis /lib/udev/rules.d
gespeichert und bekommen einen Namen nach dem folgenden Schema:
xx-Funktion.rules
Der Ausdruck xx wird dabei durch eine Zahl ersetzt. Die udev-Regeln werden der Reihe nach ausgeführt, sprich die Regel 10-Funktion.rules
wird vor der Regel 11-Funktion.rules
ausgeführt!
Von Haus aus sind bereits eine ganze Menge Regeln im System installiert.
$ ls /lib/udev/rules.d
Da bei unserer eigenen Regel der Zeitpunkt des Ausführens des Skriptes nicht so wichtig ist, kann die Regel ruhig eine etwas höhere Nummer bekommen.
$ nano /lib/udev/rules.d/80-Log_USB.rules
Der Name der Regel verrät zudem etwas über die Funktion, sodass man im Fehlerfall etc. leicht die entsprechende Regel finden kann.
Als nächstes wird die Zeile
KERNEL=="sda1", NAME="Disk"
in die Datei eingefügt. Dieser Ausdruck gibt dem udev-Daemon die folgende Anweisung:
„Wenn du ein Gerät namens sda1 findest (was z. B. ein formatierten USB-Stick ist), sollst du es Disk nennen.“
Anschließend wird die Datei gespeichert und der Daemon einmal neu gestartet. Der Neustart sorgt dafür, dass die neue Regel vom Daemon verwendet wird.
$ sudo /etc/init.d/udev restart
Wenn alles geklappt hat, erscheinen zwei grüne Ok in der Konsole und die neue Regel ist einsatzbereit.
Jetzt kann zum Test mal einen USB-Stick an den Raspberry Pi angeschlossen und geschaut werden ob die Regel angewendet wurde, indem die verfügbaren Geräte aufgelistet werden:
$ ls /dev
Der USB-Stick kann nun ganz normal mit dem Namen Disk
gemountet und anschließend weiter verwendet werden:
$ mount /dev/Disk /media
Die Erkennung eines neuen USB-Sticks funktioniert damit. Zeit um sich mit dem zweiten Teil der Regel zu beschäftigen. Für die geplante Anwendung wird die Regel um die folgende Zeile ergänzt:
KERNEL=="sd[a-z]", ACTION=="add", RUN+="/Programme/Log %k"
Als erstes wurde der Ausdruck KERNEL etwas erweitert um verschiedene Benennungen des USB-Sticks zu beachten. Im ersten Beispiel hat der udev-Daemon nur reagiert, wenn der angeschlossene USB-Stick den namen sda
bekam. Ein zweiter Stick würde dann automatisch sdb
genannt werden und damit würde die Regel nicht mehr weiter beachtet werden. Diese Problematik kann durch den Klammerausdruck umgangen werden, indem eine Benennung von sda
bis sdz
erlaubt wird.
Der nachfolgende Ausdruck ACTION
legt fest, wann eine Aktion in der Regel ausgeführt werden soll. Mögliche Parameter sind add
und remove
. In diesem Beispiel wird die Aktion also immer ausgeführt, wenn ein Gerät hinzugefügt wurde, welches unter /dev
mit dem Namen sda
– sdz
aufgeführt wird.
Der Parameter RUN
fügt der Liste an auszuführenden Programmen einen neuen Eintrag hinzu. In diesem Fall soll ein Shellskript ausgeführt werden, welches unter /Programme
abgespeichert ist. Dieses Skript sorgt dafür, dass der Name des angeschlossenen Gerätes in einer Logdatei mit einem Zeitstempel versehen abgespeichert wird. Der Zusatz %k
ist ein Speicher des udev-Daemons und er enthält den Kernelnamen des Gerätes, welches die Regel ausführt. Den Inhalt dieses Speichers übergebe ich als Kommandozeilenparameter an das Skript, welches dann später mit diesem Namen nach genaueren Informationen des Gerätes sucht.
Die Regel wäre damit fertig und kann nun abgespeichert werden. Anschließend wird der Daemon neu gestartet, damit dieser die neue Regel direkt verwendet:
$ sudo /etc/init.d/udev restart
Nun muss noch das Skript, welches die Regel ausführen soll, geschrieben werden. Dazu wird erst einmal ein neues Skript mit dem vergebenen Namen erstellt:
$ nano /Programme/Log.sh
In die erste Zeile des Skriptes wird nun
#!/bin/sh
eingefügt, damit der udev-Daemon beim ausführen des Skriptes auch weiß das es sich um ein Shellskript handelt (die sogenannte Shebang).
Danach speichere ich den Pfad der Logdatei und den Gerätenamen, welcher mir als Kommandozeilenparameter vom udev-Daemon mitgeteilt werden, in einer Variable ab:
File="/tmp/USB.log" Device=$1
Übergebene Kommandozeilenparameter lassen sich ganz einfach über $1
– $x
aufrufen und verwenden.
Im nächsten Schritt lese ich die Vendor ID des Gerätes aus und speichere auch diese in einer Variable:
Vendor=$(cat /sys/block/$Device/device/vendor)
In dem Verzeichnis /sys/block/sda/device
sind alle Informationen zu dem Gerät sda
abgelegt und können so ganz einfach über den Befehl cat
ausgelesen werden. Mit der selben Methode lese ich anschließend noch die Typenbezeichnung und die Größe des Sticks aus, welche ich ebenfalls speichere:
Typ=$(cat /sys/block/$Device/device/model) Size=$(cat /sys/block/$Device/size)
Das letzte was benötigt wird, ist das aktuelle Datum und die Uhrzeit, welche sich wie folgt einlesen lassen:
Date=`date +"%d/%m/%Y %H:%M:%S"`
Damit sind alle Komponenten für das Logfile beisammen und werden entsprechend formatiert in die Logdatei geschrieben.
echo "$Date Vendor ID: $Vendor Model: $Typ Groeße: $Size Available as $Device" >> $File
Abschließend wird das Skript gespeichert. Wird nun ein USB-Stick in den Raspberry Pi eingesteckt, so wird ein entsprechender Eintrag in der Logdatei angelegt:
Schreibe einen Kommentar