linux 在Python中确定文件系统的设备

wqsoz72f  于 2023-08-03  发布在  Linux
关注(0)|答案(8)|浏览(145)

如何使用Python来确定哪个Linux设备/分区包含给定的文件系统?
例如,在

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

字符串

avwztpqn

avwztpqn1#

你的问题是关于Linux的,所以这是(或多或少)特定于Linux的。
以下是将主/次Map到设备名称的三个变体的代码示例。

  • 解析/proc/partitions。
  • 问哈尔。哈尔还跟踪“父”设备,这意味着你可以很容易地得到磁盘以及分区。
  • 自己检查sysfs。这就是hal获取信息的地方。

我认为/proc/partitions是最简单的-它只是一个要打开和检查的文件。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()

字符串

wlp8pajw

wlp8pajw2#

看起来这篇文章有一些你的答案(仍然不确定如何从/dev/sda2条目中获取major/minor,以将其与os.stat()/返回的内容相匹配:
Device number in stat command output

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

[me@server /]$ ls -l /dev/sda2
brw-rw----    1 root     disk       8,   2 Jun 24  2004 /dev/sda2
[me@server jgaines2]$               \    \minor device number
                                     \major device number

字符串

mcdcgff0

mcdcgff03#

我最近也需要这个解决方案。在看到通过纯python获得我想要的结果的所有复杂方法后,我决定转向shell寻求帮助。

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

字符串
这正好给了我想要的东西,即文件系统挂载位置的设备字符串。
简短,甜美,并在Python中运行。:)

wz8daaqr

wz8daaqr4#

上述解决方案中的相当多的解决方案存在问题。其实这个问题也有问题。
最后一个答案(搜索/proc/mounts)不起作用:搜索“/”将匹配/proc/mounts中的每一行。即使像这样纠正也不会起作用:

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

字符串
当“/filesystem”是“/”时,通常会得到两个条目,一个是“rootfs”,另一个是实际设备。当挂载的文件系统名称中有空格时(空格在/proc/mounts中显示为\040),它也不起作用。
使用btrfs子卷会使问题变得更糟。每个子卷都是单独装载的,但它们都共享同一个设备。如果您尝试使用btrfs快照进行备份(就像我一样),那么您需要子卷名称和文件系统类型的指示。
这个函数返回一个元组(device,mountpoint,filesystem),看起来可以工作:

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


这似乎适用于我能想到的所有情况,尽管我预计仍有病理情况下,它福尔斯到位。

6kkfgxo0

6kkfgxo05#

这不是最简单的,但这会让你开始:

#!/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' +小调。

mrzz3bfm

mrzz3bfm6#

使用(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驱动器(sdb 1)的双引导笔记本电脑的输出

$ ./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"

jdg4fx2g

jdg4fx2g7#

以下是如何简单地获取设备的主要和次要编号:

import os
major, minor = divmod(os.stat('/').st_dev, 256)

字符串

czq61nw1

czq61nw18#

我的密码

#file /dir1/check.py
import os
from subprocess import *
import subprocess

#function  definition
def check():
  device = subprocess.check_output("awk '$2 == \"/\" { print $1}' /proc/mounts", shell=True)
  device_decode=device.decode()
  print(device_decode[-5:-1])
  print(device_decode[-2])
  return

#function  invocation
check()

字符串
在bash shell中运行

python3 /dir1/check.py

相关问题