web-dev-qa-db-fra.com

Comment puis-je exécuter du code chaque fois qu'un périphérique USB est (non) branché, sans nécessiter d'autorisations root?

J'ai un script que je souhaite exécuter chaque fois que je branche/déconnecte une souris ou un clavier sur mon port USB.

Il existe déjà de nombreux documents sur la configuration des règles udev pour l'exécution de scripts arbitraires lorsqu'un périphérique est branché ou débranché. Mais la configuration de ces règles nécessite des autorisations root. Et, bien que j’ai un accès root sur ma machine, , je cherche une solution ne nécessitant pas de règles Sudo, root ou d’écriture de règles udev. (pourquoi? car il sera plus facile d’exécuter, de maintenir et de distribuer)

Très probablement, la solution utilisera dbus, mais je peux me tromper.

(Au fait, je suis un utilisateur avancé et un ancien utilisateur de Gentoo, n'hésitez pas à cracher des détails techniques!)


Des solutions qui nécessitent root:

Des solutions apparemment obsolètes qui n'ont pas besoin de root:

3
Denilson Sá Maia

La question " Comment puis-je écouter les événements" Périphérique USB inséré "dans Linux, en Python? " contient un exemple très court de script Python avec pyudev . Ce script peut facilement détecter le moment où un périphérique est connecté ou déconnecté, en surveillant le device-event du sous-système usb.

De plus, pyudev est une implémentation pure-python et est disponible à la fois sur Python 2 et Python 3.

Sur la base de cet exemple de code, j'ai écrit auto_exec_xinput_xset_upon_usb_device_change.py (voir aussi la version la plus récente ). Fonctionne sur Python 2 et Python 3.

#!/usr/bin/env python

import functools
import os.path
import pyudev
import subprocess


def main():
    BASE_PATH = os.path.abspath(os.path.dirname(__file__))
    path = functools.partial(os.path.join, BASE_PATH)
    call = lambda x, *args: subprocess.call([path(x)] + list(args))

    context = pyudev.Context()
    monitor = pyudev.Monitor.from_netlink(context)
    monitor.filter_by(subsystem='usb')  # Remove this line to listen for all devices.
    monitor.start()

    for device in iter(monitor.poll, None):
        # I can add more logic here, to run only certain kinds of devices are plugged.
        call('foobar.sh')


if __== '__main__':
    main()
3
Denilson Sá Maia