在Python中可靠且“尽可能可移植”的设备名到挂载点映射方法

3 投票
4 回答
1571 浏览
提问于 2025-04-17 09:50

我想要找到一个设备的名称(比如说:/dev/disk2),并确定它被挂载在哪里(如果有的话),比如说:/mnt/cdrom 或者 /Volumes/RANDLABEL),使用Python来实现。

一种方法是运行 df 或者 mount 命令,然后解析输出结果,但这听起来不太靠谱,可能会出问题。比如说,mount 命令用 " on " 来分隔设备和挂载点。如果设备或挂载点的名称中恰好也有这个字符串,就会让结果变得模糊不清。

在Linux系统中,我可以读取 /proc/mounts 文件,但在Mac OS X上就不行了。

所以我在寻找一种可靠的方法来找到设备的挂载点,这种方法应该能够处理各种合法的设备和挂载点名称,并且尽可能具有可移植性。(我猜在Windows上可能无法做到这一点,因为我不确定它是否有类似的设备挂载点的概念。)我特别希望这种方法能在Linux和OS X上都能使用。

4 个回答

3

我觉得这个在OS X上可能不太管用,但在Linux系统中,有一种方法可以通过编程的方式来检查一个设备是否已经挂载,以及它挂载在哪些路径上。这种方法是通过dbus的 org.freedesktop.UDisks.Device 接口来实现的:

import sys, dbus

device_name = sys.argv[1]

bus = dbus.SystemBus()
ud_manager_obj = bus.get_object("org.freedesktop.UDisks", "/org/freedesktop/UDisks")
ud_manager = dbus.Interface(ud_manager_obj, 'org.freedesktop.UDisks')

device = bus.get_object('org.freedesktop.UDisks',
                        '/org/freedesktop/UDisks/devices/{0}'.format(device_name))
device_properties = dbus.Interface(device, dbus.PROPERTIES_IFACE)
if device_properties.Get('org.freedesktop.UDisks.Device', 'DeviceIsMounted'):
    for mount_path in device_properties.Get('org.freedesktop.UDisks.Device', 'DeviceMountPaths'):
        print mount_path
3

其实没有一种通用的方法可以做到这一点,所以你需要处理一些特定于平台的代码。

在OS X系统上,获取磁盘卷信息最简单、最可靠的方法就是在命令行中使用 diskutil list 命令加上 -plist 选项。然后,你可以直接用Python中的 plistlib 模块来处理输出结果。例如:

diskutil list -plist | \
   python -c 'import sys,plistlib,pprint; pprint.pprint(plistlib.readPlist(sys.stdin))'
{'AllDisks': ['disk0', 'disk0s1', 'disk0s2', 'disk0s3', 'disk1'],
 'AllDisksAndPartitions': [{'Content': 'GUID_partition_scheme',
                            'DeviceIdentifier': 'disk0',
                            'Partitions': [{'Content': 'EFI',
                                            'DeviceIdentifier': 'disk0s1',
                                            'Size': 209715200},
                                           {'Content': 'Apple_CoreStorage',
                                            'DeviceIdentifier': 'disk0s2',
                                            'Size': 499248103424},
                                           {'Content': 'Apple_Boot',
                                            'DeviceIdentifier': 'disk0s3',
                                            'Size': 650002432,
                                            'VolumeName': 'Recovery HD'}],
                            'Size': 500107862016},
                           {'Content': 'Apple_HFSX',
                            'DeviceIdentifier': 'disk1',
                            'MountPoint': '/',
                            'Size': 499097100288,
                            'VolumeName': 'main'}],
 'VolumesFromDisks': ['main'],
 'WholeDisks': ['disk0', 'disk1']}
2

(根据我之前的评论:mtab 是标准的Linux方式。在FreeBSD、Mac OS X或Solaris上没有这个东西。前两个系统有getfsstat(2)getmntinfo(2)这两个系统调用;在Solaris上可以使用getmntent(3C)。不幸的是,目前挂载的文件系统列表并没有被POSIX定义,所以在不同的平台上差别很大。)

在PyPI上有一个实验性的mount模块,属于PSI包,它似乎试图把所有特定平台的方法整合成一个简单的抽象,并且宣传说可以在Mac OS X(Darwin)、AIX、Linux和Solaris上使用。Darwin模块可能也适用于*BSD系统。

撰写回答