GNU/Linux >> Tutoriels Linux >  >> Linux

Comment exécuter un shellscript lorsque je branche un périphérique USB

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 :

  1. 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
  2. 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)
  3. 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()

Linux
  1. Comment exécuter un script lorsque des périphériques USB sont connectés ou supprimés à l'aide d'UDEV

  2. Comment exécuter un script à la fin de la session xfce

  3. Comment exécuter un script Python à partir de Java ?

  4. Comment puis-je exécuter plusieurs commandes lors de l'utilisation de find ?

  5. Exécuter le script/programme lorsque le fichier change

Comment exécuter automatiquement des commandes/scripts lors du redémarrage ou du démarrage

Comment exécuter des scripts personnalisés sur le plug-in de périphérique USB ?

Comment exécuter la commande avant la connexion de l'utilisateur sous Linux ?

Comment déclencher un événement dans le script Shell lorsqu'un périphérique USB est supprimé ?

Comment exécuter un script dans Shell lorsqu'une touche de raccourci est enfoncée ?

Comment exécuter une commande dans un script shell ?