2009-01-22 71 views

回答

50

更新:正如评论所说,哈尔是不是在新的发行支持,现在的标准是udev的,这里是一个小例子,使得使用圆滑循环,并的udev的,我把哈尔的版本历史原因。

这基本上是example in the pyudev documentation,适合与旧版本的工作,并与油嘴循环,注意过滤器应为您定制的特定需要:

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

旧版本哈尔和d -bus:

可以使用d-Bus的绑定,并听取DeviceAddedDeviceRemoved信号。 您必须检查已添加设备的功能才能选择存储设备。

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

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) 

我正在使用基于功能的过滤器。它将接受任何volume,并且会打电话给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() 
+1

我得到一个错误与此代码: dbus.exception.DBusException:org.freedesktop.DBus.Error.ServiceUnknown:名称org.freedesktop.Hal没有被任何文件。服务提供。 你认为你可以帮助我吗? – 2013-10-31 02:09:14

7

我还没有尝试写这样的程序我自己,但是我刚刚看了以下两个链接(感谢谷歌!),我认为这将是帮助:

特别是,阅读有关org.freedesktop.Hal.Manager接口,它DeviceAddedDeviceRemoved事件。 :-)

希望这有助于!

4

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

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

2

这里是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