Wenn Sie das Skript auf einem bestimmten Gerät ausführen möchten, können Sie die Hersteller- und Produkt-IDs
verwenden-
In
/etc/udev/rules.d/test.rules
:ATTRS{idVendor}=="152d", ATTRS{idProduct}=="2329", RUN+="/tmp/test.sh"
-
in
test.sh
:#! /bin/sh env >>/tmp/test.log file "/sys${DEVPATH}" >>/tmp/test.log if [ "${ACTION}" = add -a -d "/sys${DEVPATH}" ]; then echo "add ${DEVPATH}" >>/tmp/test.log fi
Mit env
, können Sie sehen, welche Umgebung von udev und mit file
eingestellt ist , finden Sie den Dateityp heraus.
Die konkreten Attribute für Ihr Gerät können Sie mit lsusb
ermitteln
lsusb
gibt
...
Bus 001 Gerät 016:ID 152d:2329 JMicron Technology Corp./JMicron USA Technology Corp. JM20329 SATA Bridge
...
Hier geht es nicht direkt um Ihre Frage, sondern um das, was Sie tun. Wenn Sie ein Backup-Skript von udev aus starten, werden Sie mit zwei Hauptproblemen konfrontiert:
- Ihr Skript wird möglicherweise gestartet, bevor das Gerät bereit ist und gemountet werden kann. Sie müssen die Bedingung KERNEL=="sd*" beibehalten, wenn Sie den /dev-Knoten zum Mounten verwenden möchten
- Noch wichtiger, wenn Ihr Skript einige Zeit zur Ausführung braucht (was bei einem Backup-Skript leicht der Fall sein kann), wird es kurz nach dem Start beendet (ca. 5 Sekunden)
- Sie werden mit vielen komplizierten Problemen mit Benutzerberechtigungen konfrontiert sein
Mein Rat ist, ein Skript in Ihrem Benutzerhaus zu erstellen, das auf eine benannte Pipe lauscht und das asynchron gestartet wird, wie :
#!/bin/bash
PIPE="/tmp/IomegaUsbPipe"
REMOTE_PATH="/path/to/mount/point"
LOCAL_PATH="/local/path/"
doSynchronization()
{
#your backup here
}
trap "rm -f $PIPE" EXIT
#If the pipe doesn't exist, create it
if [[ ! -p $PIPE ]]; then
mkfifo $PIPE
fi
#If the disk is already plugged on startup, do a syn
if [[ -e "$REMOTE_PATH" ]]
then
doSynchronization
fi
#Make the permanent loop to watch the usb connection
while true
do
if read line <$PIPE; then
#Test the message read from the fifo
if [[ "$line" == "connected" ]]
then
#The usb has been plugged, wait for disk to be mounted by KDE
while [[ ! -e "$REMOTE_PATH" ]]
do
sleep 1
done
doSynchronization
else
echo "Unhandled message from fifo : [$line]"
fi
fi
done
echo "Reader exiting"
Hinweis:Ich verwende Auto-Mount mit kde, also überprüfe ich, ob der Ordner angezeigt wird. Sie können den Parameter /dev/sd* im fifo der udev-Regel übergeben und ihn selbst im Skript einhängen. Um in das Fifo zu schreiben, vergessen Sie nicht, dass udev keine Shell ist und dass die Umleitung nicht funktioniert. Ihr RUN sollte wie folgt aussehen:
RUN+="/bin/sh -c '/bin/echo connected>> /tmp/IomegaUsbPipe'"
Ich habe eine Lösung auf https://askubuntu.com/a/516336 gepostet und kopiere die Lösung auch hierher.
Ich habe mit pyudev ein Python-Skript geschrieben, das ich im Hintergrund laufen lasse. Dieses Skript lauscht auf udev-Ereignisse (daher ist es sehr effizient) und führt den gewünschten Code aus. In meinem Fall läuft es xinput
Befehle zum Einrichten meiner Geräte (Link zur neuesten Version).
Hier ist eine Kurzversion desselben Skripts:
#!/usr/bin/env python3
import pyudev
import subprocess
def main():
context = pyudev.Context()
monitor = pyudev.Monitor.from_netlink(context)
monitor.filter_by(subsystem='usb')
monitor.start()
for device in iter(monitor.poll, None):
# I can add more logic here, to run different scripts for different devices.
subprocess.call(['/home/foo/foobar.sh', '--foo', '--bar'])
if __name__ == '__main__':
main()