2011-10-10 7 views
5

どのLinuxデバイス/パーティションに特定のファイルシステムが含まれているかをPythonでどのように判断するのですか?Pythonでのファイルシステムのデバイスの決定

>>> get_filesystem_device('/') 
/dev/sda 
>>> get_filesystem_partition('/') 
/dev/sda1 
+1

なぜ 'mount'の出力を解析しようとしませんか? –

答えて

0

それはpurdiestはありませんが、これはあなたが始めるだろう:

#!/usr/bin/python 

import os, stat, subprocess, shlex, re, sys 

dev=os.stat('/')[stat.ST_DEV] 
major=os.major(dev) 
minor=os.minor(dev) 

out = subprocess.Popen(shlex.split("df /"), stdout=subprocess.PIPE).communicate() 
m=re.search(r'(/[^\s]+)\s',str(out)) 

if m: 
    mp= m.group(1) 
else: 
    print "cannot parse df" 
    sys.exit(2) 

print "'/' mounted at '%s' with dev number %i, %i" % (mp,major,minor) 
OS X上で

:Ubuntuで

'/' mounted at '/dev/disk0s2' with dev number 14, 2 

'/' mounted at '/dev/sda1' with dev number 8, 1 

、デバイス名を取得するパーティション名からマイナー番号を切り落とすします。 OS Xでは、「s」+マイナー番号も切り詰めます。

1

この記事は、/ため何os.stat()するリターンでそれを一致させるために/dev/sda2エントリのうち、メジャー/マイナーをつかむためにどれだけまだわからない(あなたの答えのいくつかを持っているように見えます:

Device number in stat command output

>>> import os 
>>> print hex(os.stat('/')[2]) 
0x802 
    \ \minor device number 
    \major device number 

[[email protected] /]$ ls -l /dev/sda2 
brw-rw---- 1 root  disk  8, 2 Jun 24 2004 /dev/sda2 
[[email protected] jgaines2]$    \ \minor device number 
            \major device number 
+0

/proc/partitionsを解析して、maj/minをnameにマップすることができます。 –

+0

私はこの答えが本当に好きだったので、逆に/ dev/sda2(例)を見つける方法を探してきました。/dev /を解析する代わりに、対応するst_rdevを持つdevファイルを見つけることができます(暗黙の名前、 "逆dev"は "dev"と一致します:) os.stat( '/')。st_dev = = os.stat( '/ dev/sda1')。st_rdev –

+0

また、/ dev/rootが "/ dev/sda1"のマウントにあるので、これは/ proc/mounts(他の回答のように)たとえ "mount"コマンド出力が正しい/ dev/mmc *デバイスファイルを提供しても。 –

2

あなたの質問はLinuxに関するものだったので、これは多かれ少なかれLinux特有のものです。

以下は、major/minorをデバイス名にマッピングする3つのバリエーションのコード例です。

  • 解析/ proc /パーティション。
  • 質問する。 Halは「親」デバイスを追跡します。つまり、パーティションだけでなくディスクも簡単に取得できます。
  • sysfsを自分で確認してください。これはhalが情報を取得する場所です。

私は/ proc/partitionsが最も簡単だと言います。これは、開いて確認するファイルの1つです。 halはほとんどの情報を提供し、多くの詳細を抽象化します。 sysfsは/ proc/partitionsより正確であり、halを実行する必要はありません。

デスクトッププログラムの場合、私はhalに行くでしょう。組み込みシステムでは、私はsysfsに行きます。


import os 

def main(): 
    dev = os.stat("/home/").st_dev 
    major, minor = os.major(dev), os.minor(dev) 

    print "/proc/partitions says:", ask_proc_partitions(major, minor) 
    print "HAL says:", ask_hal(major, minor) 
    print "/sys says:", ask_sysfs(major, minor) 

def _parse_proc_partitions(): 
    res = {} 
    for line in file("/proc/partitions"): 
     fields = line.split() 
     try: 
      tmaj = int(fields[0]) 
      tmin = int(fields[1]) 
      name = fields[3] 
      res[(tmaj, tmin)] = name 
     except: 
      # just ignore parse errors in header/separator lines 
      pass 

    return res 

def ask_proc_partitions(major, minor): 
    d = _parse_proc_partitions() 
    return d[(major, minor)] 

def ask_hal(major, minor): 
    import dbus 

    bus = dbus.SystemBus() 
    halobj = bus.get_object('org.freedesktop.Hal', '/org/freedesktop/Hal/Manager') 
    hal = dbus.Interface(halobj, 'org.freedesktop.Hal.Manager') 

    def getdevprops(p): 
     bdevi = dbus.Interface(bus.get_object('org.freedesktop.Hal', p), 
           "org.freedesktop.Hal.Device") 
     return bdevi.GetAllProperties() 

    bdevs = hal.FindDeviceByCapability("block") 
    for bdev in bdevs: 
     props = getdevprops(bdev) 
     if (props['block.major'], props['block.minor']) == (major, minor): 
      parentprops = getdevprops(props['info.parent']) 
      return (str(props['block.device']), 
        str(parentprops['block.device'])) 

def ask_sysfs(major, minor): 
    from glob import glob 
    needle = "%d:%d" % (major, minor) 

    files = glob("/sys/class/block/*/dev") 
    for f in files: 
     if file(f).read().strip() == needle: 
      return os.path.dirname(f) 

    return None 

if __name__ == '__main__': 
    main() 
1

私は最近も、このソリューションの必要性を持っていました。私が純粋なPythonを使いたかった結果を得る複雑な方法をすべて見た後、私は助けを求めてシェルに向かうことにしました。

import subprocess 
device = subprocess.check_output("grep '/filesystem' /proc/mounts | awk '{printf $1}'", shell=True) 
print device 

私の望むもの、つまりファイルシステムがマウントされている場所のデバイス文字列です。

短くて、甘く、Pythonで動作します。 :)

0

上記の解決策の多くに問題があります。実際には質問にも問題があります。

最後の回答(searching/proc/mounts)は機能しません。 "/"を検索すると/ proc/mountsのすべての行に一致します。でも、このように、これは動作しません修正:

import subprocess 
device = subprocess.check_output("awk '$2 == \"/filesystem\" { print $1}' /proc/mounts", shell=True) 
print device 

「/ファイルシステムが」ある

「/」あなたは一般的に2つのエントリ、「rootfsの」用と実際のデバイスのための1つを取得します。マウントされたファイルシステム名にスペースが含まれていると、このファイルは動作しません(スペースは/ proc/mountsに\ 040として表示されます)。

問題はbtrfsサブボリュームで悪化します。各サブボリュームは個別にマウントされますが、すべて同じサブボリュームを共有します。バックアップのためにbtrfsスナップショットを使用しようとしている場合は、サブボリューム名とファイルシステムタイプの表示が必要です。

この関数は(デバイス、マウントポイント、ファイルシステム)のタプルを返し、動作しているようです:私は期待していますが、私は考えることができるすべてのケースのために働くようだ

import os 
def get_filesystem_partition(fs): 
    res = None 
    dev = os.lstat(fs).st_dev 
    for line in file('/proc/mounts'): 
     # lines are device, mountpoint, filesystem, <rest> 
     # later entries override earlier ones 
     line = [s.decode('string_escape') for s in line.split()[:3]] 
     if dev == os.lstat(line[1]).st_dev: 
      res = tuple(line) 
    return res 

はまだ病的あることそれがビットになるケース。

0

(Linux)を使用する方法について、コマンド(/ sbinに/ BLKID)

$ uname --kernel-name --kernel-release 
Linux 3.2.0-4-amd64 

$ python --version 
Python 2.7.3 

BLKID方法 -

#!/usr/bin/env python           

import subprocess 

sys_command = "/sbin/blkid" 
proc = subprocess.Popen(sys_command, 
         stdout=subprocess.PIPE, 
         shell=True) 

# proc.communicate() returns a tuple (stdout,stderr)       
blkid_output = proc.communicate()[0] 

print blkid_output 

ここで(アンマウント)USBドライブとのデュアルブートのラップトップ上の出力だが(sdb1など)ここで

$ ./blkid.py 
/dev/sda1: LABEL="RECOVERY" UUID="xxxx-xxxx" TYPE="vfat" 
/dev/sda2: LABEL="OS" UUID="xxxxxxxxxxxxxxx" TYPE="ntfs" 
/dev/sda5: UUID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" TYPE="ext4" 
/dev/sda6: UUID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" TYPE="swap" 
/dev/sda7: UUID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" TYPE="ext4" 
/dev/sdb1: LABEL="CrunchBang" TYPE="iso9660" 
0

は、あなたは、単に主要なデバイス番号とマイナー番号を得ることができる方法です。

import os 
major, minor = divmod(os.stat('/').st_dev, 256) 
関連する問題