it-swarm.com.de

Starten Sie die Anwendung (GUI), nachdem Sie ein USB-Gerät angeschlossen haben

Ich verwende Ubuntu-gnome 16.04 LTS 4.4.0-62-generic.

Ich möchte Folgendes tun: Führen Sie entweder ...

  • (a) eine Anwendung ( GUI ) [/path/to/my_app.desktop]
  • oder (b) ein interaktives Skript in einem Terminal [z. B .: $ gnome-terminal -x /path/to/script.sh]

... wenn ein Mount eines beliebigen (USB) Geräts erkannt wird.

Die Ausführung auf dem X-Server des Benutzers scheint obligatorisch zu sein, da abhängig von der ausgeführten Anwendung/dem ausgeführten Skript unterschiedliche Benutzereingaben erforderlich sind. es kann nicht einfach im hintergrund laufen.

In den letzten 2 Tagen habe ich intensiv recherchiert und mit beiden experimentiert, dev-rules und systemd.services. Mein erneut auftretendes Problem ist, dass einer der letzteren Ansätze X-Authentifizierung erforderlich. Obwohl es sicher (verschlungene) Möglichkeiten gibt, die Authentifizierung durchzuführen, mag ich die Idee nicht die angeborene Systemsicherheit zu verletzen durch Exportieren der $ XAUTHORITY-Variablen von root in die Sitzung des Benutzers ...

Ich nehme an, es sollte einen alternativen Weg geben, um Folgendes zu erreichen:

  1. erkennen, wann/ob ein neues (USB-) Gerät angeschlossen wurde
  2. starten einer Anwendung/eines Skripts (im Terminal) mit USER-Berechtigungen auf dem Benutzerdesktop (d. h. Xsession des Benutzers?)
  3. (optional: den Gerätenamen als Variable übergeben)

(Erstellung von mount-spezifischen .config-Dateien ?; org.gnome.desktop.media-handling ?; Autostart-Skript unter/home/$ USERNAME/media .mounts ?; Bearbeitung von/etc/fstab; ...?)

Für Hinweise wäre ich sehr dankbar.

3
brunuser

(Alte Antwort, neue Antwort weiter unten)


Führen Sie ein Skript oder einen Befehl aus, der ausgeführt werden soll, wenn ein USB-Laufwerk angeschlossen wird

Wenn Sie aus irgendeinem Grund keine udev Regeln oder etwas Komplizierteres verwenden möchten, verwenden Sie das folgende Skript.

Das Ausführen des Skripts mit dem Befehl zum Ausführen als Argument reicht aus, um die Aufgabe zu erledigen.

Das Drehbuch:

#!/usr/bin/env python3
import subprocess
import time
import sys

cmd = " ".join(sys.argv[1:])

def get_mountedlist():
    return [(item.split()[0].replace("├─", "").replace("└─", ""),
             item[item.find("/"):]) for item in subprocess.check_output(
            ["/bin/bash", "-c", "lsblk"]).decode("utf-8").split("\n") if "/" in item]

def identify(disk):
    command = "find /dev/disk -ls | grep /"+disk
    return "usb" in subprocess.check_output(["/bin/bash", "-c", command]).decode("utf-8")

mounted1 = get_mountedlist()
while True:
    time.sleep(4)
    mounted2 = get_mountedlist()
    if [d for d in mounted2 if all([not d in mounted1, d != "/", identify(d[0]) == True])]:
        subprocess.Popen(["/bin/bash", "-c", cmd])
    mounted1 = mounted2

Benutzen

  1. Kopieren Sie das Skript in eine leere Datei und speichern Sie es als run_usbactions.py
  2. Führen Sie das Skript (z. B.) mit dem folgenden Befehl aus:

    python3 /path/to/run_usbactions.py <command_to_run> <optional_args>
    

    In meinem Test verwendete ich z.

    python3 /path/to/run_usbactions.py gedit file
    

    file mit gedit öffnen, sobald ein USB-Laufwerk angeschlossen ist.

  3. Wenn alles funktioniert, fügen Sie es zu Startup Applications hinzu: Dash> Startup Applications> Add. Fügen Sie den Befehl hinzu:

    python3 /path/to/run_usbactions.py <command_to_run> <optional_args>
    

Erläuterung

  • In der Funktion get_mountedlist() liest das Skript alle vier Sekunden die Ausgabe von lsblk.

  • Für den Fall, dass zusätzliche Partitionen oder Geräte gemountet sind, wird die Ausgabe (z. B.) des Befehls:

    find /dev/disk -ls | grep sdc1
    

    enthält die Zeichenfolge usb und identifiziert das bereitgestellte Laufwerk als USB-Laufwerk.
    Wenn ich es mir jetzt ansehe, könnte ich es sehr gut durch eine "pythonischere" Methode ersetzen, anstatt durch einen Systemaufruf, aber da ich es aus einem älteren Skript kopiert habe, habe ich es (noch) nicht getan .

  • anschließend if das neue laufwerk ist ein usb, der befehl (+ mögliche args), wie in " ".join(sys.argv[1:]) gesetzt, wird ausgeführt.




BEARBEITEN

(29. Dezember 2017)

Mit Pyudev

Seitdem ich Pyudev "getroffen" habe, dachte ich, ich sollte die große Vereinfachung und klarere Bedienung teilen, die es bringt. Ein einfaches Skript zum Ausführen einer Aktion beim Einfügen eines USB-Geräts lautet dann:

#!/usr/bin/env python3
import pyudev
import subprocess
import sys

cmd = " ".join(sys.argv[1:])

monitor = pyudev.Monitor.from_netlink(pyudev.Context())
monitor.filter_by('block')

for device in iter(monitor.poll, None):
    if all([
        device['ACTION'] == "add", 'ID_FS_TYPE' in device,
        device['ID_USB_DRIVER'] == "usb-storage",
        ]):
        print("added", device.get('ID_FS_LABEL'))
        subprocess.Popen(["/bin/bash", "-c", cmd])

Verwendung

Stellen Sie sicher, dass pyudev installiert ist:

Sudo apt install python3-pyudev

Weitere Anweisungen sind genau ähnlich.

3
Jacob Vlijm