Wie führe ich ein Skript aus, wenn ein bestimmtes Flash-Laufwerk aktiviert ist?

46

Gibt es eine Möglichkeit, ein Skript auszuführen, wenn ein bestimmtes USB-Gerät gemountet ist?

Ich speichere meine Videos auf einem separaten USB-Stick und möchte ein Skript ausführen, mit dem der Videoordner auf dem USB-Gerät an den Ordner im Ausgangsordner angehängt wird.

Braiam
quelle

Antworten:

31

Mit systemd gibt es jetzt eine viel schönere Lösung . Sie erstellen einen Service, der von Ihren Medien abhängt und gewünscht wird, zB:/etc/systemd/system/your.service

[Unit]
Description=My flashdrive script trigger
Requires=media-YourMediaLabel.mount
After=media-YourMediaLabel.mount

[Service]
ExecStart=/home/you/bin/triggerScript.sh

[Install]
WantedBy=media-YourMediaLabel.mount

Dann müssen Sie den Dienst starten / aktivieren:
sudo systemctl start your.service
sudo systemctl enable your.service

Nach dem Einhängen löst systemd Ihr Triggerskript aus. Der Vorteil gegenüber der udev-Regel besteht darin, dass das Skript erst nach dem Einhängen und nicht erst nach dem Hinzufügen des Systemgeräts gestartet wird.

Anwendungsfall : Ich habe eine verschlüsselte Partition, die ich automatisch sichern möchte. Nach dem Hinzufügen des Geräts muss ich das Passwort eingeben. Wenn ich das Sicherungsskript mit udev verknüpft habe, wird versucht, das Skript zu dem Zeitpunkt auszuführen, an dem ich das Kennwort eingebe. Dies schlägt fehl.

Ressource: Skripten mit udev

Hinweis: Sie finden Ihre Geräteeinheit mit:systemctl list-units -t mount

sumid
quelle
Ich hoffe, dass der April 2016 bald kommt. Für das nächste Ubuntu LTS ist systemd aktiviert. AFAIK die nette Lösung von oben benötigt Ubuntu 15.04 oder neuer.
Guettli
Oh, ich dachte, Systemd ist bereits in Ubuntu. Ich
laufe gerade Debian
@sumid Wenn ich es unter ~ / .config / systemd ablegen möchte, funktioniert es dann?
Khurshid Alam
4
Toll! Getestet in Debian Jessie. Vergessen Sie nicht, Ihren Dienst zu aktivieren systemctl enable your.service. Die Skriptdatei muss ausführbar sein.
Corni
1
Für mich schlägt dies fehl. Wenn ich versuche, den Dienst zu starten, beklagt er sich mit "Unit media-bb.mount not found". Ich habe die FS meines USB-Sticks (FAT32) "bb" genannt, um sicherzustellen, dass keine seltsamen Zeichen enthalten sind und es nicht zu lang oder so ist. Ich versuchte , die Requires=, After=und WantedBy=Linien sowohl mit media-bb.mountund media-BB.mountweil Nautilus zeigt mir das Volumen als „BB“, nicht „bb“. Gleiche Fehlermeldung mit Ausnahme der Großschreibung. Was ist los mit dir? Muss ich diesen media-<something>.mountDienst irgendwie erstellen ?
UTF-8
29

Beginnen Sie, indem Sie Ihr Gerät in suchen lsusb. Notiere die ID (zB 0a81:0101)

Erstellen Sie eine neue udev- Regeldatei in /etc/udev/rules.d/via sudoedit /etc/udev/rules.d/100-mount-videos.rulesund fügen Sie dort eine neue Regel wie folgt ein:

ACTION=="add", ATTRS{idVendor}=="0a81", ATTRS{idProduct}=="0101", RUN+="/home/your_username/bin/mount_videos.sh"

Beachten Sie, wie ich die ID von verwendet habe lsusb.

Dann müssen Sie nur noch das Skript schreiben, um die Arbeit zu erledigen. Ein einfacher Befehl zum Einhängen sollte funktionieren. Möglicherweise müssen Sie dort einen sleep 5Befehl eingeben, um auf die Initialisierung des Dateisystems zu warten (wenn Sie gnome für die Hauptbereitstellung überlassen - aber Sie können ihn zuerst bereitstellen und benötigen dann möglicherweise nicht den Ruhezustand).

Hinzufügung von Allan: Lang laufende Skripte könnten "alle weiteren Ereignisse für dieses oder ein abhängiges Gerät" blockieren. In meiner Mint-Manpage heißt es weiter: "Langfristige Aufgaben müssen sofort vom Ereignisprozess selbst getrennt werden." Es wird kein Tipp gegeben, wo Sie die entsprechenden Fähigkeiten erwerben können.

Antwort von Oli: Pack es so ein: https://askubuntu.com/a/106359/449

Oli
quelle
4
Ich könnte vorschlagen, dem Befehl "RUN" das Präfix "su your_user -c" voranzustellen, damit das Skript nicht mit Root-Rechten ausgeführt wird.
Kees Cook
3
@ Kees Da das Ziel hier die Erhöhung ist, ist es möglicherweise eine gute Idee, Root-Privs zu behalten. Anstatt das Skript zu Hause beim Benutzer zu lassen, können Sie es möglicherweise in /root/oder an einem Ort aufbewahren, an dem nur root es bearbeiten kann.
Oli
2
Dies beantwortet die Frage nicht. Die Frage stellt , wie man ein Skript ausgeführt werden soll , wenn ein USB - Laufwerk montiert . Diese Antwort sagt , wie ein Skript ausführen zu tun , die Halterungen ein USB - Laufwerk funktioniert , wenn es eingefügt . Der Unterschied ist mir wichtig, weil ich ein solches Skript habe (für eine Digitalkamera); Ohne das Skript kann oder kann das Laufwerk beim Einfügen gemountet werden (abhängig von den Benutzereinstellungen) und nur wenn das Laufwerk gemountet ist, möchte ich etwas tun (kopiere die Images). Daher wird mein Skript (das ausgeführt wird, wenn das Laufwerk hinzugefügt wird) häufig zur falschen Zeit ausgeführt.
Reinier Post
Dies ist ein unglaublich spezifischer (spröder) Weg, um dies zu erreichen. @sumid Antwort mehr anwendbar auf moderne Distribution mit Systemd
MrMesees
8

Eine andere Möglichkeit, die Werte für ATTRS {idVendor} und ATTRS {idProduct} (getestet in Ubuntu 12.04) abzurufen, ist:

  1. Finden Sie heraus, wo Ihr USB eingehängt ist:

    $ mount | grep /dev/sd*
    

    Dies zeigt so etwas wie das Folgende:

    /dev/sdb on /media/SOMEDIR type vfat ...
    
  2. Verwenden Sie udevadm, um die Geräteinformationen abzurufen:

    udevadm info -q all -n /dev/sdb | grep -E -i -w '.*VENDOR_ID.*|.*MODEL_ID.*'
    

    Die Ausgabe sollte ungefähr so ​​aussehen:

    E: ID_MODEL_ID=001a
    E: ID_VENDOR_ID=002b
    
  3. Verwenden Sie nun die Modell-ID für ATTRS {idProduct} und die Lieferanten-ID für ATTRS {idVendor}.

    ACTION=="add", ATTRS{idVendor}=="002b", ATTRS{idProduct}=="001a" ...
    
emont01
quelle
1

In Nautilus können Sie unter Bearbeiten> Einstellungen> Medien "Andere Aktion" und dann "Kostümbefehl" auswählen. für verschiedene Arten von Medien ausgeführt werden. Zu diesem Zeitpunkt ist das USB-Laufwerk bereits gemountet, aber Sie können es wahrscheinlich trotzdem (mit einem Kostümbefehl) mit dem Ordner verknüpfen, in dem das Laufwerk angezeigt werden soll. Ich konnte nicht feststellen, ob dies einfacher oder besser ist als die Verwendung von udev.

Speck
quelle
Trägt der Befehl ein Kostüm? oder ein Kostüm?
Erjoalgo
1

Wenn Sie die Kontrolle Ihres Dateimanagers (Nautilus, Konquerer, Gnome usw.) über das Aktivieren und Deaktivieren Ihres Geräts nicht beeinträchtigen möchten, empfehle ich, den udev-Weg nicht einzuschlagen.

Verwenden Sie stattdessen udisks-glue, wenn Ihr System udisks verwendet (fast alle tun dies).

Erstellen Sie nach der Installation einfach eine solche Konfigurationsdatei ~/.udisks-glue.confin Ihrem Home-Verzeichnis.

In meinem folgenden Beispiel werden die GPS-Assist-Daten auf meiner Kamera jedes Mal aktualisiert, wenn ich die SD-Karte einstecke.

filter BT16EXTREME {
  optical = false
  partition_table = false
  usage = filesystem
  label = BT16EXTREME
}
match BT16EXTREME {
  post_mount_command = "/home/bernhard/update-gps-assist-data.pl %mount_point"
}

Stellen Sie anschließend sicher, dass udisks-glue beim Booten oder Einloggen startet. Dh über die Startanwendungen von gnome

xro
quelle
1
Unterstützt nicht udev2 :-(
sumid
0

@ sumids Antwort hat ein Problem. Sie sollten den Dienst nicht starten. Sie müssen es nur aktivieren.

Datei: /etc/systemd/system/your.service

[Unit]
Description=My flashdrive script trigger
Requires=media-YourMediaLabel.mount
After=media-YourMediaLabel.mount

[Service]
ExecStart=/any_path_even_inside_the_mount_point/script.sh

[Install]
WantedBy=media-YourMediaLabel.mount

Aktivieren Sie dann den Dienst:

sudo systemctl enable your.service

Das ist alles.

Hinweis: Ihr Medienetikett finden Sie unter:sudo systemctl list-units -t mount

Hinweis 2: Wenn der Dienst aus irgendeinem Grund fehlschlägt (z. B. wenn das Skript nicht ausführbar ist), ändert sich <old_mount_point_name>1Ihr Bereitstellungspunkt zum nächsten Mal, wenn Sie das USB-Gerät bereitstellen. Um dieses Problem zu beheben, müssen Sie nur ausführensudo systemctl reset-failed

sgon00
quelle