我如何在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绑定并侦听DeviceAdded
和DeviceRemoved
信号。 您必须检查已添加设备的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
接口及其DeviceAdded
和DeviceRemoved
事件。 🙂
希望这可以帮助!
我认为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.0
testingPython 3.5。