English 中文(简体)
我该如何在Linux中使用Python监听USB设备插入事件?
原标题:
  • 时间:2009-01-22 14:09:59
  •  标签:

我想在Linux中为Amarok编写一个Python脚本,以自动将stackoverflow播客复制到我的播放器。当我插入播放器时,它会挂载驱动器,复制任何未处理的播客,并弹出播放器。如何监听“插入”事件?我已经查看了hald,但找不到好的示例。

最佳回答

更新:如评论中所述,Hal在最近的发行版中不受支持,现在的标准是udev。这是一个利用glib循环和udev的小例子,我保留了Hal版本出于历史原因。

这基本上是 pyudev 文档中的示例,适应于旧版本,并使用 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:

You can use D-Bus bindings and listen to DeviceAdded and DeviceRemoved signals. You will have to check the capabilities of the Added device in order to select the storage devices only.

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

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

并且您需要连接到您感兴趣的信号的侦听器,在本例中为DeviceAdded

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

我正在使用基于功能的过滤器。它将接受任何音量并调用do_something。如果您想查找更适合您需求的查询或了解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()
问题回答

这里是五行的解决方案。

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

我尚未尝试编写这样的程序,不过我刚刚查看了以下两个链接(感谢谷歌!),我认为它们会很有帮助:

特别是阅读有关org.freedesktop.Hal.Manager界面及其DeviceAddedDeviceRemoved事件的内容。 :-)

希望这可以帮助!

我认为D-Bus就像Chris所说的那样工作,但如果你正在使用KDE4,你可以使用Solid框架以类似于KDE4“新设备提示器”小部件的方式使用它。

该小程序的C++源代码在这里,展示了如何使用Solid检测新设备。使用PyKDE4来绑定这些库的Python代码,如这里所示。





相关问题
热门标签