2011-10-10 34 views
5

如何使用Python来确定哪个Linux设备/分区包含给定的文件系统?在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:

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

在Ubuntu:

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

来获得设备名称,砍掉从分区名称的次要号码。在OS X上,还可以删除's'+次要号码。

1

它看起来像这个帖子有一些你的答案(仍然不知道只是如何抓住主要/次要出/dev/sda2项与匹配起来什么os.stat()回报/

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 /分区来将maj/min映射到名字。 –

+0

我真的很喜欢这个答案,所以我一直在查找如何找到/ dev/sda2(在示例中)。而不是解析/ proc /分区,你可以遍历/ dev /并找到具有相应st_rdev(暗示名称,“反向dev”匹配“dev”:) os.stat('/')的开发文件。st_dev = =/dev/sda1')。st_rdev –

+0

这比在/ proc/mounts(比如在其他答案中)更好,因为raspberry pi(例如)具有/ dev/root作为“/即使“mount”命令输出提供了正确的/ dev/mmc *设备文件.. –

2

你的问题是关于Linux的,所以这是(或多或少)linux特定的。

以下是将主要/次要映射到设备名称的三种变体的代码示例。

  • 解析/ proc /分区。
  • 询问hal。 Hal还会跟踪“父级”设备,这意味着您可以轻松获取磁盘以及分区。
  • 自己检查sysfs。这是hal从中获取信息的地方。

我想说/ proc /分区是最简单的 - 它只是一个文件打开和检查。 hal给你提供了大部分信息,并且提取了很多细节。 sysfs可能被认为是更正确的/ proc /分区,并且不需要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获得结果的复杂方法之后,我决定转向shell寻求帮助。

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

这给了我想要的东西,我的文件系统安装位置的设备字符串。

短,甜,并运行在蟒蛇。 :)

0

上述解决方案中有相当多的问题。这个问题实际上也存在问题。

最后一个答案(搜索/ proc/mounts)不起作用:搜索“/”将匹配/ proc/mounts中的每一行。即使更正此类似,这将不起作用:

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

当“/文件系统”是“/”你通常会得到两个入口,一个是“根文件系统”,一个针对实际设备。当挂载的文件系统名称中有空格时(该空间在/ 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)的BLKID命令(/ sbin目录/ BLKID)

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

$ python --version 
Python 2.7.3 

-

#!/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) 
相关问题