2010-12-07 20 views
2

私はdbusを使ってUSBドライブを検出し、検出されたときにマウントされているディレクトリを表示するプログラムをpythonで書いています。ここでは、コードは次のとおりpythonで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

"p1 ... p2 ...行が間違っていますか?" do_something "の一部ですか? – mjhm

+1

私に提案をさせてください - dbusでこれを行うことは、inotify (カーネル拡張機能)。もしそれをビルドするオプションがあるなら(またはすでにビルドされている場合)、マウントディレクトリを見ることができます。http://pyinotify.sourceforge.net/また、サブプロセスdf/grep/awk - あなたが望むのは/ proc/diskstatsにあり、数行のネイティブPythonで解凍できます。 – synthesizerpatel

+0

@mjhm、貧弱な字下げについては申し訳ありません:実際のコードではdo_somethingの一部ですが、 –

答えて

1

あなたの元の質問では、競合状態に殴られているようです。

マウントプロセスが完了する前にデバイスが挿入され、コードが実行されます。

Popenコールをwhileループに入れてみてください(下記参照)。

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 

これは少しリソースが多いソリューションですが、必要な処理を行う必要があります。