我如何收听';插入usb设备';Linux中的事件,Python中的事件?

我如何收听';插入usb设备';Linux中的事件,Python中的事件?,python,linux,usb,Python,Linux,Usb,我想在Linux中为Amarok编写一个Python脚本,自动将stackoverflow播客复制到我的播放器上。当我插入播放机时,它将装入驱动器,复制任何挂起的播客,然后弹出播放机。如何收听“插入”事件?我浏览了hald,但找不到一个好的例子。我自己也没有试过编写这样的程序,但我只是查看了以下两个链接(感谢谷歌!),我认为这会有所帮助: (其中讨论了如何使用Python访问D-Bus) (讨论HAL如何将事件发布到D-Bus) 特别是,请阅读org.freedesktop.Hal.Mana

我想在Linux中为Amarok编写一个Python脚本,自动将stackoverflow播客复制到我的播放器上。当我插入播放机时,它将装入驱动器,复制任何挂起的播客,然后弹出播放机。如何收听“插入”事件?我浏览了hald,但找不到一个好的例子。

我自己也没有试过编写这样的程序,但我只是查看了以下两个链接(感谢谷歌!),我认为这会有所帮助:

  • (其中讨论了如何使用Python访问D-Bus)
  • (讨论HAL如何将事件发布到D-Bus)
特别是,请阅读
org.freedesktop.Hal.Manager
界面及其
DeviceAdded
DeviceRemoved
事件。:-)


希望这有帮助

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


该applet的C++源,它显示了如何使用Solid来检测新设备。使用PyKDE4对这些库进行Python绑定,如图所示。

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

这基本上是相同的,适用于旧版本和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-Bus绑定并监听
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")
您需要将侦听器连接到您感兴趣的信号,在本例中是
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()

这里有一个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\u 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

在Python3.5上测试,pyudev==0.21.0

我收到一个错误代码:dbus.exception.DBusException:org.freedesktop.dbus.error.ServiceUnknown:任何.service文件都没有提供org.freedesktop.Hal的名称。你认为你能帮我吗?@EtienneLepage Lepitre Hal现在已经不推荐了,一般来说,这个解决方案已经不起作用了:(添加了使用udev的解决方案。哇,你能相信我们过去在没有宽带连接到internet的设备上收听播客吗?