我如何在Linux和Python中監聽“usb設備插入”事件?

[英]How can I listen for 'usb device inserted' events in Linux, in Python?


I'd like to write a Python script for Amarok in Linux to automatically copy the stackoverflow podcast to my player. When I plug in the player, it would mount the drive, copy any pending podcasts, and eject the player. How can I listen for the "plugged in" event? I have looked through hald but couldn't find a good example.

我想為Amarok在Linux中編寫一個Python腳本,將stackoverflow播客自動復制到我的播放器中。當我插入播放器時,它會掛載驅動器,復制任何掛起的播客,並彈出播放器。我怎樣才能聽到“插入”事件呢?我查了哈德的資料,但找不到好的例子。

4 个解决方案

#1


51  

Update: As said in comments, Hal is not supported in recent distributions, the standard now is udev, Here is a small example that makes use of glib loop and udev, I keep the Hal version for historical reasons.

更新:正如評論中所說,Hal在最近的發行版中不受支持,現在的標准是udev,這里有一個使用glib循環和udev的小例子,出於歷史原因,我保留了Hal版本。

This is basically the example in the pyudev documentation, adapted to work with older versions, and with the glib loop, notice that the filter should be customized for your specific needing:

這基本上是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()

Old version with Hal and d-bus:

舊版本的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.

您可以使用D-Bus綁定並偵聽deviceadd和DeviceRemoved信號。您必須檢查添加設備的功能,以便只選擇存儲設備。

Here is a small example, you can remove the comments and try it.

這里有一個小例子,您可以刪除注釋並嘗試它。

import dbus
import gobject

class DeviceAddedListener:
    def __init__(self):

You need to connect to Hal Manager using the System Bus.

您需要使用系統總線連接到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")

And you need to connect a listener to the signals you are interested on, in this case DeviceAdded.

你需要連接一個監聽器到你感興趣的信號,在這個例子中是deviceadd。

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

I'm using a filter based on capabilities. It will accept any volume and will call do_something with if, you can read Hal documentation to find the more suitable queries for your needs, or more information about the properties of the Hal devices.

我在使用基於功能的過濾器。它將接受任何卷,並將調用do_something與if,您可以閱讀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)

Example function that shows some information about the volume:

顯示有關卷的一些信息的示例函數:

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

#2


7  

I haven't tried writing such a program myself, however I've just looked at the following two links (thanks Google!), which I think will be of help:

我自己還沒有嘗試過寫這樣的程序,但是我只看了下面兩個鏈接(謝謝谷歌!)

  • dbus-python tutorial (which talks about how to use Python to access D-Bus)
  • dbus-python教程(討論如何使用Python訪問D-Bus)
  • HAL 0.5.10 Specification (which talks about how HAL publishes events to D-Bus)
  • HAL 0.5.10規范(討論HAL如何將事件發布到D-Bus)

In particular, read about the org.freedesktop.Hal.Manager interface, and its DeviceAdded and DeviceRemoved events. :-)

特別是,閱讀關於org.freedesktop.Hal.Manager接口及其deviceadd和DeviceRemoved事件的文章。:-)

Hope this helps!

希望這可以幫助!

#3


4  

I think D-Bus would work as Chris mentioned, but if you're using KDE4, you might use the Solid framework in a manner similar to the KDE4 "New Device Notifier" applet.

我認為D-Bus會像Chris提到的那樣工作,但是如果您使用KDE4,您可能會使用與KDE4“新設備通知器”applet類似的實體框架。

The C++ source for that applet is here, which shows how to use Solid to detect new devices. Use PyKDE4 for Python bindings to these libraries, as shown here.

這個applet的c++源代碼在這里,它展示了如何使用Solid來檢測新設備。將PyKDE4用於這些庫的Python綁定,如圖所示。

#4


2  

Here is a solution in 5 lines.

這是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.

Save this to a file say usb_monitor.py, run python monitor.py. Plug any usb and it will print device details

保存到一個文件,比如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

Tested on Python 3.5 with pyudev==0.21.0.

在Python 3.5上測試,pyudev= 0.21.0。


注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:https://www.itdaan.com/blog/2009/01/22/4f559579d13744914108d0b1fd5f9feb.html



 
粤ICP备14056181号  © 2014-2020 ITdaan.com