在Python中检查Linux上的USB驱动器?

4
我正在尝试用Python制作一个系统,用于检查USB驱动器上是否存在文件,如果没有设备,它会等待dbus系统注册新设备,然后再次检查。我已经完成了检查mtab部分和检查文件是否存在的部分,也让dbus部分工作了起来,但目前我遇到的问题是当驱动器被注册时,无法退出dbus部分,以便我可以检查mtab和检查文件。希望这讲得有意义。对于糟糕的编码风格,我表示歉意-我才刚开始学习。以下是我目前所拥有的:
#!/usr/bin/env python
import string, time, os, dbus, gobject, sys
from dbus.mainloop.glib import DBusGMainLoop

def device_added_callback(device):
  print ("Block device added. Check if it is partitioned")
  usbdev = "".join(device.split("/")[5:6])
  if usbdev.endswith("1") == 1:
    print ("Block device is partitioned. Waiting for it to be mounted.")
    # This is where I need to break out of the USB bit so I can check mtab and then check the file exits.

def waitforusb():
  DBusGMainLoop(set_as_default=True)
  bus = dbus.SystemBus()
  proxy = bus.get_object("org.freedesktop.UDisks", "/org/freedesktop/UDisks")
  iface = dbus.Interface(proxy, "org.freedesktop.UDisks")
  devices = iface.get_dbus_method('EnumerateDevices')()
  usbdev = iface.connect_to_signal('DeviceAdded', device_added_callback)
  mainloop = gobject.MainLoop()
  mainloop.run()
  return usbdev

def checkusbispresent():
  f = open("/etc/mtab")
  lines = f.readlines()
  f.close()
  for line in lines:
    mtpt = "".join(line.split()[1:2])
    isthere = mtpt.find("media")
    if isthere == 1:
      return mtpt

def checkserialfile(mtpt):
  _serialfile=mtpt+"/serial.lic"
  if ( not os.path.isfile(_serialfile)):
    print("Error: serial file not found, please download it now")
  else:
    print("Serial file found, attempting validation... ")

usbdrive = checkusbispresent()
if ( usbdrive is not None ):
  checkserialfile(usbdrive)
else:
  print ("USB drive is not present. Please add it now.")
  added = waitforusb()
  print added

mainloop.run() 是它卡在那里的那一行代码吗? - Cameron Sparr
@CameronSparr 它并不是卡住了,而是没有失败和退出。它之所以卡住是因为当waitforusb()被调用时,它会执行它应该执行的操作,并且device_added_callback(device)会被正确地调用,USB块设备会被列出,.join和.endswith也能正常工作(所以我可以检查分区是否已注册...就是这样),但是然后我就不知道该怎么做才能走出dbus的范畴。我尝试了各种while True; break循环...但都无济于事。 - Grant
我不确定我理解问题... print语句是否被执行?你所说的“break out”是什么意思? - Cameron Sparr
我认为你关于它卡在 mainloop.run() 上的想法可能是正确的,但今天我的大脑已经变成了浆糊,我无法想出如何让它等待udev返回块设备已添加(或在循环中轮询),然后继续检查mtab、检查文件位。 - Grant
链接说我可以使用mainloop.quit()来终止它,但我不确定在哪里放置它。如果我将其放置在mainloop.run()之后,它将不会被执行;如果我将其放置在def device_added_callback(device):内的某个位置,则会抛出异常,因为该def内不存在mainloop! - Grant
1个回答

1

知道了!

我非常怀疑这是最优雅的解决方案,但我会在以后的某个阶段攻击优雅。

我将主循环(global mainloop)设为全局变量,然后就可以从device_added_callback中访问它了:

def waitforusb():
  DBusGMainLoop(set_as_default=True)
  bus = dbus.SystemBus()
  proxy = bus.get_object("org.freedesktop.UDisks", "/org/freedesktop/UDisks")
  iface = dbus.Interface(proxy, "org.freedesktop.UDisks")
  devices = iface.get_dbus_method('EnumerateDevices')()
  iface.connect_to_signal('DeviceAdded', device_added_callback)
  global mainloop
  mainloop = gobject.MainLoop()
  mainloop.run()

def device_added_callback(device):
  usbdev = "".join(device.split("/")[5:6])
  if usbdev.endswith("1") == 1:
    mainloop.quit()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接