在Python中打印USB挂载点的问题
我有一个用Python写的程序,它使用dbus来检测插入的USB驱动器,并在检测到时打印出它们挂载的目录。以下是代码:
import dbus import gobject import shutil import os import subprocess import time class DeviceAddedListener: def __init__(self): 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") self.hal_manager.connect_to_signal("DeviceAdded", self._filter) 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 p1 = subprocess.Popen(["df", "-h"], stdout=subprocess.PIPE) p2 = subprocess.Popen(["grep", device_file], stdin=p1.stdout, stdout=subprocess.PIPE) p3 = subprocess.Popen(["awk", "{ print $6 }"], stdin=p2.stdout, stdout=subprocess.PIPE) path = p3.communicate()[0] print path if __name__ == '__main__': from dbus.mainloop.glib import DBusGMainLoop DBusGMainLoop(set_as_default=True) loop = gobject.MainLoop() DeviceAddedListener() loop.run()
问题是,当我打印路径变量(USB的挂载点)时,它却打印出一个空字符串。不过,当我在Python的交互式解释器中执行这些相同的命令(比如Popen()等)时,它能正确打印出路径(/media/03CB-604C)。这是什么原因呢?如果对我的代码有任何修改建议,我会非常感激。提前谢谢大家!
1 个回答
1
在你最开始的问题中,看起来你可能遇到了一个竞争条件的问题。
也就是说,设备已经插入了,但你的代码在设备挂载完成之前就开始执行了。
你可以尝试把Popen的调用放在一个循环里(见下面的代码)。
path = ""
count = 0
while count < 10 and path == "":
p1 = subprocess.Popen(["df", "-h"], stdout=subprocess.PIPE)
p2 = subprocess.Popen(["grep", device_file], stdin=p1.stdout, stdout=subprocess.PIPE)
p3 = subprocess.Popen(["awk", "{ print $6 }"], stdin=p2.stdout, stdout=subprocess.PIPE)
path = p3.communicate()[0]
count += 1
if path == "":
time.sleep(1)
print path
这个方法可能会消耗一些资源,但应该能达到你想要的效果。