2009-01-22 47 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