Si vous souhaitez exécuter le script sur un appareil spécifique, vous pouvez utiliser les identifiants du fournisseur et du produit
-
Dans
/etc/udev/rules.d/test.rules
:ATTRS{idVendor}=="152d", ATTRS{idProduct}=="2329", RUN+="/tmp/test.sh"
-
en
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
Avec env
, vous pouvez voir quel environnement est défini à partir d'udev et avec file
, vous découvrirez le type de fichier.
Les attributs concrets de votre appareil peuvent être découverts avec lsusb
lsusb
donne
...
Bus 001 Périphérique 016 :ID 152d:2329 JMicron Technology Corp. / JMicron USA Technology Corp. JM20329 Pont SATA
...
Il ne s'agit pas directement de votre question mais de ce que vous faites. Si vous démarrez un script de sauvegarde à partir d'udev, vous serez confronté à deux problèmes principaux :
- Votre script peut être lancé avant que l'appareil ne soit prêt et puisse être monté, vous devez conserver la condition KERNEL=="sd*" si vous souhaitez utiliser le nœud /dev pour le monter
- Plus important encore, si votre script prend un certain temps à s'exécuter (ce qui peut facilement être le cas avec un script de sauvegarde), il sera tué peu de temps après son démarrage (environ 5 s)
- Vous serez confronté à de nombreux problèmes complexes d'autorisation utilisateur
Mon conseil est de créer un script dans votre user home qui écoute un pipe nommé et qui sera lancé de façon asynchrone comme :
#!/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"
Note :j'utilise le montage automatique avec kde donc je vérifie que le dossier s'affiche. Vous pouvez passer le paramètre /dev/sd* dans le fifo de la règle udev et le monter vous-même dans le script. Pour écrire dans le fifo n'oubliez pas qu'udev n'est pas un shell et que la redirection ne fonctionne pas. Votre RUN devrait ressembler à :
RUN+="/bin/sh -c '/bin/echo connecté>> /tmp/IomegaUsbPipe'"
J'ai posté une solution sur https://askubuntu.com/a/516336 et je copie-colle également la solution ici.
J'ai écrit un script Python en utilisant pyudev que je laisse tourner en arrière-plan. Ce script écoute les événements udev (c'est donc très efficace) et exécute le code que je veux. Dans mon cas, il exécute xinput
commandes pour configurer mes appareils (lien vers la version la plus récente).
Voici une version courte du même script :
#!/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()