我如何在Linux中使用Python来监听“插入usb设备”事件?

我想在Linux中为Amarok编写一个Python脚本来自动将stackoverflow播客复制到我的播放器。 当我插入播放器时,它将挂载驱动器,复制任何未完成的播客,并popup播放器。 我怎样才能听“插入”事件? 我已经看穿了,但找不到一个好例子。

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

这基本上是pyudev文档中的示例 ,适用于旧版本,并使用glib循环,注意filter应根据您的特定需求进行自定义:

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-Bus绑定并侦听DeviceAddedDeviceRemoved信号。 您必须检查已添加设备的function才能select存储设备。

这里是一个小例子,你可以删除评论并尝试。

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

您需要使用系统总线连接到Hal Manager。

  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") 

您需要将侦听器连接到您感兴趣的信号,在这种情况下, DeviceAdded

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

我正在使用基于function的filter。 它将接受任何volume并会调用do_something ,如果您可以阅读Hal文档以find更适合您的需求的查询,或者了解有关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() 

我还没有尝试自己编写这样的程序,但是我只是看了下面的两个链接(感谢Google!),我认为这将有所帮助:

  • dbus-python教程 (讲述如何使用Python访问D-Bus)
  • HAL 0.5.10规范 (说明HAL如何将事件发布到D-Bus)

具体来说,请阅读有关org.freedesktop.Hal.Manager接口及其DeviceAddedDeviceRemoved事件。 🙂

希望这可以帮助!

我认为D-Bus可以像克里斯提到的那样工作,但是如果你使用的是KDE4,你可以使用类似于KDE4“New Device Notifier”小程序的Solid框架。

这个applet的C ++源代码就在这里 ,它展示了如何使用Solid来检测新的设备。 如下所示,使用PyKDE4将Python绑定到这些库。

这是5行的解决scheme。

 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 

pyudev==0.21.0testingPython 3.5。