J'utilise Ubuntu-gnome 16.04 LTS 4.4.0-62-generic.
Je voudrais faire la suite: Run soit ...
... chaque fois qu'un montage de tout (USB) périphérique est reconnu.
L'exécution sur le serveur X de l'utilisateur semble obligatoire, car il est nécessaire de modifier les entrées de l'utilisateur en réponse à l'application/au script en cours d'exécution. il ne peut pas simplement fonctionner en arrière-plan.
Au cours des 2 derniers jours, j'ai effectué des recherches approfondies et expérimenté les deux, udev-rules et systemd.services . Le problème récurrent est que l'une ou l'autre de ces dernières approches nécessite l'authentification X . Bien qu'il existe des moyens (compliqués) de rendre l'authentification effective, je n'aime pas l'idée de violer la sécurité du système inné en exportant les variables $ XAUTHORITY de la racine à la session de l'utilisateur ...
Je suppose qu'il devrait y avoir une autre façon de faire ce qui suit:
(création de fichiers .config spécifiques au montage ?; org.gnome.desktop.media-manipulation ?; autostart-script observant/home/$ USERNAME/media .mounts ?; édition/etc/fstab; ...?)
Toute allusion serait hautement appréciée.
(Ancienne réponse, nouvelle réponse plus bas)
Si, pour une raison quelconque, vous ne souhaitez pas utiliser les règles udev
ou quelque chose de plus compliqué, utilisez le script ci-dessous.
Exécuter simplement le script, avec votre commande à exécuter en argument, fera le travail.
#!/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
run_usbactions.py
Testez le script en exécutant (par exemple) la commande:
python3 /path/to/run_usbactions.py <command_to_run> <optional_args>
Dans mon test, j'ai utilisé par exemple:
python3 /path/to/run_usbactions.py gedit file
pour ouvrir file
avec gedit une fois le lecteur USB connecté.
Si tout fonctionne correctement, ajoutez-le à Applications de démarrage: Dash> Applications de démarrage> Ajouter. Ajoutez la commande:
python3 /path/to/run_usbactions.py <command_to_run> <optional_args>
Une fois toutes les quatre secondes, dans la fonction get_mountedlist()
, le script lit le résultat de lsblk
.
Dans le cas où supplémentaire des partitions ou des périphériques sont montés, la sortie de (par exemple) la commande:
find /dev/disk -ls | grep sdc1
inclura la chaîne usb
et identifiera le lecteur monté en tant que lecteur USB.
En le regardant maintenant, je pourrais très bien le remplacer par une méthode plus "pythonique", plutôt que par un appel système, mais comme je l’ai copié à partir d’un script plus ancien, je ne l’ai pas (encore) .
" ".join(sys.argv[1:])
est exécutée.(29 décembre 2017)
Depuis que j'ai "rencontré" Pyudev, je pensais que je devrais partager la simplification majeure et le fonctionnement plus clair qu'elle apporte. Un script simple pour effectuer toute action lors de l'insertion d'un périphérique USB devient alors:
#!/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])
Assurez-vous que pyudev
est installé:
Sudo apt install python3-pyudev
Les autres instructions sont exactement similaires.