GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Wie führe ich ein Shellscript aus, wenn ich ein USB-Gerät anschließe?

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:

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

Linux
  1. Wie führt man benutzerdefinierte Skripts auf dem USB-Geräte-Plug-in aus?

  2. Wie führe ich einen Befehl vor der Benutzeranmeldung unter Linux aus?

  3. Wie fügt man Zeilenumbrüche in Variablen im Bash-Skript ein?

  4. Wie werden Parameter eingestellt, wenn Bash-Skript an Bash übergeben wird?

  5. Wie führe ich ein Python-Skript von Java aus aus?

Wie führe ich ein Sh-Skript von einer Desktop-Verknüpfung aus?

Wie führe ich einen Befehl in einem Shell-Skript aus?

So führen Sie ein Skript aus, wenn USB-Geräte mit UDEV angeschlossen oder entfernt werden

So führen Sie ein Skript aus, wenn die xfce-Sitzung endet

Wie führe ich mehrere Befehle aus, wenn ich find verwende?

Systemd:So führen Sie das Skript nur beim Herunterfahren aus (nicht beim Neustart)