ubuntuusers.de

per udev USB2/3 detektieren

Status: Ungelöst | Ubuntu-Version: Lubuntu 22.04 (Jammy Jellyfish)
Antworten |

Marantkurz

Anmeldungsdatum:
7. September 2023

Beiträge: 760

USB2/3 detektieren

Kam durch das Thema auf die Idee mal etwas zu "spielen".

Ziel ist beim Ein/Ausstecken angezeigt zu bekommen, mit welchem USB Standard/ Datenrate gesteckt/gezogen wurde.

Das:

SUBSYSTEM=="usb", ATTRS{speed}=="480", RUN+="/bin/su <USER> --command='...'"
SUBSYSTEM=="usb", ATTRS{speed}=="480", RUN+="..."

(lgw. momentan nur USB2), tut es nicht. Schlägt tlw. fehlerhaft an. Also, es geht nur um die Bedingung, die Anweisung ist OK.

edit

Scheint doch zu funktioniere Vllt. mag das mal Jmd. testen.

TNTMaster

Anmeldungsdatum:
30. Juli 2009

Beiträge: 875

Interessant is ja nur die Geschwindigkeit beim Anstecken des Geräts. Mit zenity kann man das auch schön am Desktop anzeigen lassen.

udev Regel:

ACTION=="add", ENV{DEVTYPE}=="usb_device", SUBSYSTEMS=="usb", RUN+="/bin/su <USER> --command='/PFAD/ZU/SKRIPT.sh $id $attr{idVendor}:$attr{idProduct} $attr{speed}'"

/PFAD/ZU/SKRIPT.sh:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
#!/bin/bash

product=$(cat /sys/bus/usb/devices/$1/product)
case $3 in
    12) usb=1.0 ;;
   480) usb=2.0 ;;
  5000) usb=3.0 ;;
 10000) usb=3.1 ;;
 20000) usb=3.2 ;;
 40000) usb=4   ;;
 80000) usb=4v2 ;;
     *) usb=N/A ;;
esac
DISPLAY=:0 zenity --info --width=400 --title="USB Info" --text="Product:   $product  (ID: $2)\nSpeed:       $3 Mbit/s,   USB $usb" &

Darf getestet und verbessert werden 😉

Marantkurz

(Themenstarter)

Anmeldungsdatum:
7. September 2023

Beiträge: 760

Oh, Danke! @TNTMaster, das gefällt mir, werde das nutzen.

Habe es nur leicht angepasst, u.a kam Timeout noch dazu. Falls noch Jmd. das haben mag:

DISPLAY=:0 zenity --timeout=10 --info --width=400 --title="USB Info" --text="Product:\n$product   (ID: $2)\nSpeed:\n$3 Mbit/s,   USB $usb" &

Per notify-send sollte es auch gehen:

DISPLAY=:0 notify-send -i dialog-information -a "USB Info" -t 10000 "Product: $product (ID: $2)" "Speed: $3 Mbit/s, USB $usb" &

Interessant wird bei Hubs die Ausgabe,

hatte auch mal Einträge ATTRS{speed}=="12" bis ATTRS{speed}=="10000" gesetzt, auch schön. 😎

$product müsste sich auch von udev mitgeben lassen, mal schauen was man noch weiteres lustiges ausgeben lassen könnte.

edit

ID_VENDOR_FROM_DATABASE
ID_MODEL_FROM_DATABASE
#hätte gedacht, daß so:
$env{ID_VENDOR_FROM_DATABASE}

wären mglw. noch Kandidaten zum übergeben, bekomme das bisher nicht hin.

TNTMaster

Anmeldungsdatum:
30. Juli 2009

Beiträge: 875

Mann kann es noch ein wenig aufhübschen, denn zenity (wie auch yad) beherschen Pango Markup. Hab noch den Hersteller mit rein genommen. Die Werte von udev gleich mit übergeben lassen, hab ich noch nicht getestet.

ACTION=="add", ENV{DEVTYPE}=="usb_device", SUBSYSTEMS=="usb", RUN+="/bin/su <USER> --command='/PFAD/ZU/SKRIPT.sh $id $attr{idVendor}:$attr{idProduct} $attr{speed} \"$attr{manufacturer}\" \"$attr{product}\"'"
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
#!/bin/bash

case $3 in
    12) usb=1.0 ;;
   480) usb=2.0 ;;
  5000) usb=3.0 ;;
 10000) usb=3.1 ;;
 20000) usb=3.2 ;;
 40000) usb=4   ;;
 80000) usb=4v2 ;;
     *) usb=N/A ;;
esac
DISPLAY=:0 zenity --info --width=400 --title="USB Info" \
    --text="<span font='Monospace 14' weight='bold'>Vendor   </span>$4 \
          \r<span font='Monospace 14' weight='bold'>Product  </span>$5 \
          \r<span font='Monospace 14' weight='bold'>USB-ID   </span>$2 \
          \r<span font='Monospace 14' weight='bold'>Speed    </span>$3 Mbit/s \
          \r<span font='Monospace 14' weight='bold'>Modus    </span>USB $usb" &

Edit: udev Regel jetzt mit Übergabe von Hersteller + Product und Skript entsprechend geändert.

Marantkurz

(Themenstarter)

Anmeldungsdatum:
7. September 2023

Beiträge: 760

ein wenig aufhübschen

Sicher, lasse es derzeit ohne Formatierung, mal sehen. Habe hier noch Bus/Ports(also $1)u. bMaxPower(allerdings von /sys/bus/usb/devices/*(könnte ggf. langsam eng werden, die übergebene Parameteranzahl sonst)) mit reingenommen. Kann nicht schaden, eher nützlich bei Fehlersuche. Momentan s. Bild.

Was ID_VENDOR_FROM_DATABASE u. ID_MODEL_FROM_DATABASE die ich schon mit dabei haben will, betrifft, überlege ich es von einer externen Seite zu holen.(oder mglw. befindet sich eine Aufstellung schon im System, ziemlich sicher sogar) Quasi Notlösung.

edit

mglw. befindet sich eine Aufstellung

Hier ist schon mal die Liste:(Bin mir noch nicht im Klaren wie am besten in Block auslesen, danach sollte ja grep reichen)

/var/lib/usbutils/usb.ids

Klinke mich momentan aus, melde mich wieder.

Bilder

TNTMaster

Anmeldungsdatum:
30. Juli 2009

Beiträge: 875

Mir reichen die Infos so vollkommen aus, viel mehr Interessantes gibt es sowieso nicht anzuzeigen. Mir war es wichtig, die Datenrate/USB-Modus zu wissen, wenn ich z.B. eine externe Platte anschließe. Klar kann man sich auch mit lsusb -tv anzeigen lassen, aber so ist das ganz nett. Übersicht einiger Parameter, die von udev übergeben werden können:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
$id                               Bus/Port des Geräts
$attr{idVendor}:$attr{idProduct}  USB-ID, wie sie von lsusb angezeigt wird
$attr{speed}                      Übertragungsrate in Mbit/s
\"$attr{manufacturer}\"           Hersteller (muß gequotet werden, da Leerzeichen, etc. vorkommen können)
\"$attr{product}\"                Modellbezeichnung (muß gequotet werden, da Leerzeichen, etc. vorkommen können)
$attr{bMaxPower}                  Max. Stromaufnahme

# Mit folgendem Befehl kann man sich mögliche Parameter für das Gerät ausgeben lassen,
# <ID> ist zu ersetzen mit dem Wert von Bus/Port ($id), z.B. 2-1.2
udevadm info --attribute-walk --path=/sys/bus/usb/devices/<ID>

Was ID_VENDOR_FROM_DATABASE u. ID_MODEL_FROM_DATABASE ... von einer externen Seite zu holen

Nicht nötig, "manufacturer" und "product" kann man von udev übergeben lassen, siehe meinen letzten Post. Den hatte ich noch mal editiert, was du wohl übersehen hast.

Marantkurz

(Themenstarter)

Anmeldungsdatum:
7. September 2023

Beiträge: 760

Mir reichen die Infos so vollkommen aus, viel mehr Interessantes gibt es sowieso nicht anzuzeigen. ... Nicht nötig, "manufacturer" und "product" kann man von udev übergeben lassen,

Naja, manchmal bingt das was. Bsp:

Product:
USB Flash Memory   (ID: 0930:653d)

1-3.4,   max: 100mA
Speed:
480 Mbit/s,   USB 2.0__60Mbyte/s

0930  Toshiba Corp.
	653d  Kingston DataTraveler 2.0 Stick (1GB)

Oben "product"/"manufacturer"(manufacturer leer) unten

ID_VENDOR_FROM_DATABASE u. ID_MODEL_FROM_DATABASE. Sicher, man kann das auch manuell suchen.

Das wäre der Test:

udevadm monitor --environment --udev | grep -i datab

Das Ganze, ein kleines feines praktisches Tool. Offb. sehen das nur Zwei so. 😉

TNTMaster

Anmeldungsdatum:
30. Juli 2009

Beiträge: 875

Das hab ich inzwischen auch festgestellt, als ich ein paar USB Geräte probiert hab, bei einen Stick ist product und manufacturer leer, bei einem anderen steht als product nur "USB Mass Storage Device" und manufacturer ist leer. In der USB Datenbank per lsusb wird der Stick richtig bezeichnet.

Hab dann noch folgendes eingebaut und laß es anzeigen ($2 ist die USB-ID)

usb_name=$(lsusb -d $2 | cut -d " " -f 7-)

Noch schöner wärs, direkt anhand der USB-ID direkt in /usr/share/misc/usb.ids zu suchen, aber das hab ich mit awk, grep, etc bisher nicht wirklich hinbekommen.

shiro

Anmeldungsdatum:
20. Juli 2020

Beiträge: 1214

Noch schöner wärs, direkt anhand der USB-ID direkt in /usr/share/misc/usb.ids zu suchen, aber das hab ich mit awk, grep, etc bisher nicht wirklich hinbekommen.

Probier mal den folgenden "sed" Befehl in folgendem Script (usbid.sh).

$ echo '#!/bin/bash
# Zeigt Infos über USB-Geräte-ID ($1)
USBid=${1:-0930:653d}
IFS=":" read mfg dev <<<$USBid
sed -n "/^$mfg /{h;:a;n;s/^[0-9a-f]/&/;tb;s/^\t$dev/&/;Ta;H;:b;x;s/\n\t/ | /;p}" </usr/share/misc/usb.ids
' >usbid.sh
$ # Aufruf z.B. 
$ . usbid.sh 04f2:b221
04f2  Chicony Electronics Co., Ltd | b221  integrated camera
$ 

Erläuterung des "sed" Befehls:

  • h - Zeile mit mfg am Zeilenanfang im "hold" merken

  • :a - Label a, um hierher zu springen

  • n - neue Zeile in "pattern" lesen

  • s - testen, ob am Zeilenanfang eine Hex-Nummer steht = Ende der Liste der Devices

  • tb - Wenn neuer mfg gefunden, hüpfe nach Label :b und mache Ausgabe

  • s - testen, ob Zeile mit TAB und Device-Nummer beginnt

  • Ta - wenn Device-Nummer nicht gefunden wird, hüpfe zum Label :a

  • H - hänge gefundene Device-Zeile aus "pattern" an "hold" space an.

  • :b - Label b, um hierher zu springen

  • x - tausche "hold" und "pattern" space

  • s - Ersetze \n (NL) und \t (TAB) durch " | "

  • p - Gebe den Inhalt im "pattern" aus

Marantkurz

(Themenstarter)

Anmeldungsdatum:
7. September 2023

Beiträge: 760

👍, funktioniert, Danke!

Beides erfüllt den Zweck. @shiro's usb.ids sed Lösung sind für mich die berühmten böhmischen Dörfer noch.

Zusammengefasst, so eingebunden, wer es braucht:

IFS=":" read mfg dev <<<$2
usb_name_von_usbids=`cat /usr/share/misc/usb.ids | sed -n "/^$mfg /{h;:a;n;s/^[0-9a-f]/&/;tb;s/^\t$dev/&/;Ta;H;:b;x;s/\n\t/ | /;p}"`

oder/und:

usb_name_von_lsusb=$(lsusb -d $2 | cut -d " " -f 7-)

TNTMaster

Anmeldungsdatum:
30. Juli 2009

Beiträge: 875

1
2
\"$env{ID_VENDOR_FROM_DATABASE}\"
\"$env{ID_MODEL_FROM_DATABASE}\"

Die beiden udev Parameter sind oben etwas kurz gekommen, deshalb hier noch mal. Es scheint so, als liefern diese die gleichen Daten, wie in der Datei usb.ids stehen. Die Modell-Bezeichnung meiner externen SSD ist dort nicht enthalten (leer), aber lsusb zeigt sie zumindest richtig an.

Als Alternative zu shiro's Lösung (die ich trotz Erklärung nicht wirklich verstehe), mein Versuch die Infos aus usb.ids zu greppen. ($2 ist die USB-ID)

1
2
3
vendor_block=$(sed -n "/^${2%:*} /,/^[a-f0-9]\{4\} /p" /usr/share/misc/usb.ids | head -n -1)
manufacturer=$(sed -E "/^${2%:*} +/!d; s|^${2%:*} +||" <<<"$vendor_block")
product=$(sed -E "/^\t+${2#*:}/!d; s|^\t+${2#*:} +||" <<<"$vendor_block")

Falls sich jemand für die Module interessiert, die für den Betrieb nötig sind, kann das noch einbauen:

1
2
3
4
5
for i in /sys/bus/usb/drivers/*/$1*; do
    [ ! -d "$i" ] && modules="No modules loaded" && break
    modules="$(cut -d "/" -f 6 <<<"$i"), $modules"
done
modules="${modules%, }"

shiro

Anmeldungsdatum:
20. Juli 2020

Beiträge: 1214

Ach, du möchtest die Strings ohne die Nummern den Variablen gleich zuweisen und dabei nur den "s" Befehl verwenden. Das geht auch so:

$ cat >x.sh <<*EOF*
echo "2: \$2"
eval \$(sed -n "/^\${2%:*} /,/^[a-f0-9]\{4\} / \
s/^\${2%:*} \+\(.*\)/manufacturer='\1'/p;\
s/^\t\${2#*:} \+\(.*\)/product='\1'/p" </usr/share/misc/usb.ids)
*EOF*
$ 
$ manufacturer="";product=""
$ echo "m=$manufacturer,p=$product"
m=,p=
$ 
$ . x.sh parameter1 0930:653d
2: 0930:653d
$ 
$ echo "m=$manufacturer,p=$product"
m=Toshiba Corp.,p=Kingston DataTraveler 2.0 Stick (1GB)
$ 
Antworten |