uptime · 1404 days · 23 posts published · last deploy 1 day, 10 hours ago build:passing rss
~ / linux / wie-erstellt-man-einen-symlink-für-ttyusbx.md
Linux · 31. Juli 2022 · ~8min · 73b93d9

Wie erstellt man einen Symlink für ttyUSBx?

Das USB-Geräte-Chaos nach dem Reboot – und die udev-Regel, die es ein für alle Mal löst.

>
devmaker.net
author · 73b93d9 · 2022-07-31
x
USB Symlink Linux Header.jpg 1408×768
USB Symlink Linux Header
Jeder, der einen Raspberry Pi oder Homelab-Server mit mehreren USB-Geräten betreibt, kennt das Spiel: Nach einem Neustart sind die ttyUSB-Nummern vertauscht, Zigbee2MQTT greift auf den Z-Wave-Stick zu, und nichts funktioniert mehr. Die Ursache ist simpel – Linux vergibt USB-Nummern nicht deterministisch. Die Lösung ist eine udev-Regel, die jedem Gerät einen festen Symlink gibt. Fünf Minuten Arbeit, nie wieder dran denken.

Das Problem: Nach dem Reboot ist alles durcheinander

Jeder, der einen Raspberry Pi oder Homelab-Server mit mehreren USB-Geräten betreibt, kennt das: Ein Zigbee-Coordinator-Stick steckt an /dev/ttyUSB0, ein Z-Wave-Stick an /dev/ttyUSB1. Alles läuft – bis zum nächsten Reboot. Plötzlich sind die Nummern vertauscht, Zigbee2MQTT greift auf den Z-Wave-Stick zu, und das Smarthome steht Kopf.

Die Ursache: Linux vergibt die ttyUSB-Nummern in der Reihenfolge, in der die USB-Geräte beim Booten erkannt werden. Die ist nicht deterministisch. Die Lösung ist eine udev-Regel, die jedem Gerät einen festen Symlink-Namen gibt – einmal einrichten, nie wieder dran denken.

Kurzversion

Mit udevadm info die Vendor- und Product-ID des USB-Geräts auslesen, eine Regel in /etc/udev/rules.d/ anlegen, udevadm trigger – fertig. Das Gerät ist ab sofort unter einem fixen Namen wie /dev/ttyZCOORD erreichbar.

USB-Gerät identifizieren

Zuerst brauchen wir die eindeutigen IDs des USB-Geräts. Steck den Stick ein und lies die Attribute aus:

udevadm info --name=/dev/ttyUSB0 --attribute-walk

Die Ausgabe ist lang – wir suchen nach idVendor und idProduct. Diese Kombination identifiziert den Gerätetyp eindeutig:

  looking at parent device '/devices/platform/.../usb1/1-1/1-1.2':
    KERNELS=="1-1.2"
    SUBSYSTEMS=="usb"
    DRIVERS=="usb"
    ATTRS{bDeviceClass}=="00"
    ATTRS{bMaxPower}=="100mA"
    ATTRS{idProduct}=="ea60"
    ATTRS{idVendor}=="10c4"
    ATTRS{manufacturer}=="Silicon Labs"
    ATTRS{product}=="slae.sh cc2652rb stick - slaesh's iot stuff"

In diesem Fall: idVendor="10c4" und idProduct="ea60" – ein Silicon Labs CP2102-basierter Zigbee-Stick. Die Werte notieren, die brauchen wir gleich.

udev-Regel anlegen

Jetzt erstellen wir eine Regel-Datei, die beim Einstecken oder Booten automatisch einen festen Symlink anlegt:

sudo nano /etc/udev/rules.d/98-usb-device.rules

Inhalt der Datei – idVendor und idProduct mit deinen eigenen Werten ersetzen, SYMLINK ist der Name, unter dem das Gerät künftig erreichbar sein soll:

KERNEL=="ttyUSB?", SUBSYSTEMS=="usb", ATTRS{idProduct}=="ea60", ATTRS{idVendor}=="10c4", SYMLINK+="ttyZCOORD"
Achtung bei mehreren identischen Sticks

Hast du zwei USB-Geräte mit identischer Vendor/Product-ID (z.B. zwei Silicon-Labs-Sticks), reicht diese Methode allein nicht. Du musst dann zusätzlich nach ATTRS{serial} oder dem physischen USB-Port (KERNELS) filtern. Sonst landen beide auf dem gleichen Symlink.

Regel anwenden und testen

Die neuen Regeln laden – ein voller Reboot ist nicht nötig:

sudo udevadm trigger

Prüfen, ob der Symlink da ist:

ls -l /dev/ttyZ*
lrwxrwxrwx  1 root root  7 28. Jun 00:17 /dev/ttyZCOORD -> ttyUSB0

Ab jetzt zeigt /dev/ttyZCOORD immer auf den richtigen Stick – egal welche ttyUSB-Nummer Linux ihm beim Booten gibt. In Zigbee2MQTT, Z-Wave JS oder ESPHome einfach den Symlink als Device-Pfad eintragen.

Wo das im Homelab relevant wird

Dieses Pattern kommt bei mir ständig vor:

  • Zigbee-Coordinator (CC2652, SkyConnect) → /dev/ttyZCOORD
  • Z-Wave-Stick (Aeotec Z-Stick) → /dev/ttyZWAVE
  • ESP32-Flasher via UART → /dev/ttyESPFLASH

Gerade wenn mehrere Sticks gleichzeitig am selben Host hängen, ist das die einzig vernünftige Lösung. Ohne udev-Regeln ist jeder Reboot ein Glücksspiel.

Was ich weggelassen habe

Ehrliche Abgrenzung

Ein paar Dinge, die hier bewusst nicht behandelt werden:

  • USB-Geräte ohne ttyUSB-Interface (z.B. reine HID-Devices) – da greift ein anderer udev-Mechanismus.
  • systemd-Dependencies. Wenn ein Service beim Booten den Symlink erwartet, bevor udev die Regel ausführt, braucht man eine After=-Abhängigkeit. Das ist ein eigenes Thema.
  • Docker-Passthrough. Wenn der Stick in einem Docker-Container genutzt wird, muss zusätzlich --device /dev/ttyZCOORD in den Container gemappt werden.

Fazit

Eine udev-Regel ist fünf Minuten Arbeit und spart einem jahrelang Debugging nach jedem Reboot. Für jedes USB-Gerät, das du dauerhaft betreibst – Zigbee, Z-Wave, GPS, Seriell-Adapter – gehört ein fester Symlink angelegt. Das ist einer dieser "warum habe ich das nicht sofort gemacht"-Momente.

// responses (0)
> echo "your thoughts" >> wie-erstellt-man-einen-symlink-für-ttyusbx.responses

Schreibe einen Kommentar

Wird für die Bestätigung benötigt