代码之家  ›  专栏  ›  技术社区  ›  joeforker

如何在Linux和Python中监听“USB设备插入”事件?

  •  35
  • joeforker  · 技术社区  · 16 年前

    我想在Linux中为Amarok编写一个python脚本,自动将stackoverflow播客复制到我的播放器中。当我插入播放器时,它会安装驱动器,复制任何挂起的播客,并弹出播放器。如何收听“接通电源”事件?我查过霍尔德,但找不到一个好的例子。

    4 回复  |  直到 9 年前
        1
  •  53
  •   Jaime Soriano    11 年前

    更新 :正如评论中所说,HAL在最近的发行版中不受支持,现在的标准是udev,下面是一个使用glib循环和 UDEV 因为历史原因,我保留了HAL版本。

    这基本上是 example in the pyudev documentation ,适用于旧版本和glib循环,请注意,过滤器应根据您的特定需要进行定制:

    import glib
    
    from pyudev import Context, Monitor
    
    try:
        from pyudev.glib import MonitorObserver
    
        def device_event(observer, device):
            print 'event {0} on device {1}'.format(device.action, device)
    except:
        from pyudev.glib import GUDevMonitorObserver as MonitorObserver
    
        def device_event(observer, action, device):
            print 'event {0} on device {1}'.format(action, device)
    
    context = Context()
    monitor = Monitor.from_netlink(context)
    
    monitor.filter_by(subsystem='usb')
    observer = MonitorObserver(monitor)
    
    observer.connect('device-event', device_event)
    monitor.start()
    
    glib.MainLoop().run()
    

    带HAL和D-BUS的旧版本:

    您可以使用D总线绑定并监听 DeviceAdded DeviceRemoved 信号。 为了只选择存储设备,您必须检查添加的设备的功能。

    下面是一个小例子,您可以删除注释并尝试它。

    import dbus
    import gobject
    
    class DeviceAddedListener:
        def __init__(self):
    

    您需要使用系统总线连接到HAL管理器。

            self.bus = dbus.SystemBus()
            self.hal_manager_obj = self.bus.get_object(
                                                  "org.freedesktop.Hal", 
                                                  "/org/freedesktop/Hal/Manager")
            self.hal_manager = dbus.Interface(self.hal_manager_obj,
                                              "org.freedesktop.Hal.Manager")
    

    在本例中,您需要将监听器连接到您感兴趣的信号上 装置附加 .

            self.hal_manager.connect_to_signal("DeviceAdded", self._filter)
    

    我使用的是基于功能的过滤器。它会接受任何 volume 并将呼叫 do_something 有了if,您可以阅读hal文档,以查找更适合您需要的查询,或者更多有关hal设备属性的信息。

        def _filter(self, udi):
            device_obj = self.bus.get_object ("org.freedesktop.Hal", udi)
            device = dbus.Interface(device_obj, "org.freedesktop.Hal.Device")
    
            if device.QueryCapability("volume"):
                return self.do_something(device)
    

    显示有关卷的一些信息的示例函数:

         def do_something(self, volume):
            device_file = volume.GetProperty("block.device")
            label = volume.GetProperty("volume.label")
            fstype = volume.GetProperty("volume.fstype")
            mounted = volume.GetProperty("volume.is_mounted")
            mount_point = volume.GetProperty("volume.mount_point")
            try:
                size = volume.GetProperty("volume.size")
            except:
                size = 0
    
            print "New storage device detectec:"
            print "  device_file: %s" % device_file
            print "  label: %s" % label
            print "  fstype: %s" % fstype
            if mounted:
                print "  mount_point: %s" % mount_point
            else:
                print "  not mounted"
            print "  size: %s (%.2fGB)" % (size, float(size) / 1024**3)
    
    if __name__ == '__main__':
        from dbus.mainloop.glib import DBusGMainLoop
        DBusGMainLoop(set_as_default=True)
        loop = gobject.MainLoop()
        DeviceAddedListener()
        loop.run()
    
        2
  •  7
  •   Søren Løvborg    14 年前

    我自己也没试过写这样的程序,不过我只看了以下两个链接(谢谢谷歌!)我认为这将有助于:

    特别是,阅读 org.freedesktop.Hal.Manager 接口及其 DeviceAdded DeviceRemoved 事件。-)

    希望这有帮助!

        3
  •  4
  •   Matt J Jørgen Fogh    16 年前

    我认为D-Bus可以像Chris提到的那样工作,但是如果您使用的是kde4,那么您可能会以类似于kde4“新设备通知程序”小程序的方式使用坚实的框架。

    应用程序的C++源代码是 here 显示如何使用Solid检测新设备。使用pykde4将python绑定到这些库,如图所示 here .

        4
  •  4
  •   Chillar Anand    9 年前

    这里有5行的解决方案。

    import pyudev
    
    context = pyudev.Context()
    monitor = pyudev.Monitor.from_netlink(context)
    monitor.filter_by(subsystem='usb')
    
    for device in iter(monitor.poll, None):
        if device.action == 'add':
            print('{} connected'.format(device))
            # do something very interesting here.
    

    把这个保存到一个文件 usb_monitor.py 运行 python monitor.py . 插入任何USB,它将打印设备详细信息

    → python usb_monitor.py 
    Device('/sys/devices/pci0000:00/0000:00:14.0/usb1/1-6/1-6:1.0') connected
    Device('/sys/devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1:1.0') connected
    

    在python 3.5上测试 pyudev==0.21.0 .