如何获取连接到系统的USB驱动器的目录?

6

我需要获取用于USB驱动器创建的目录路径(我认为它类似于/media/user/xxxxx),因为我正在制作一个简单的USB大容量存储设备浏览器。有人能建议最好/最简单的方法吗?我正在使用Ubuntu 13.10机器,并将在Linux设备上使用它。

需要用Python实现。


除了解析“mount”输出之外,您还可以考虑其他方法。您可以从中获取设备和路径,也可以参考https://dev59.com/-FDTa4cB1Zd3GeqPNvvL?rq=1 - m.wasowski
@m.wasowski,您能否提供一个简要的解释/相关问题/链接来说明如何做到这一点?我既是Python新手,也是Linux新手。 - Flame of udun
我现在不能详细解释,否则我会被女友当场杀死...但如果你愿意,几个小时后我可以回答你。 - m.wasowski
@m.wasowski 没问题 - Flame of udun
5个回答

15

这应该可以让您入门:

#!/usr/bin/env python

import os
from glob import glob
from subprocess import check_output, CalledProcessError

def get_usb_devices():
    sdb_devices = map(os.path.realpath, glob('/sys/block/sd*'))
    usb_devices = (dev for dev in sdb_devices
        if 'usb' in dev.split('/')[5])
    return dict((os.path.basename(dev), dev) for dev in usb_devices)

def get_mount_points(devices=None):
    devices = devices or get_usb_devices() # if devices are None: get_usb_devices
    output = check_output(['mount']).splitlines()
    is_usb = lambda path: any(dev in path for dev in devices)
    usb_info = (line for line in output if is_usb(line.split()[0]))
    return [(info.split()[0], info.split()[2]) for info in usb_info]

if __name__ == '__main__':
    print get_mount_points()

它是如何运作的?

首先,我们解析/sys/block中的sd*文件(来自https://dev59.com/-FDTa4cB1Zd3GeqPNvvL#3881817),以过滤掉USB设备。稍后调用mount并解析输出,仅为那些设备的行。

当然,可能会存在某些边缘情况,导致此方法不起作用,例如可移植性问题等。或者,有更好的方法可以实现。但是,有关更多信息,您应该寻求在SuperUser或ServerFault上寻求帮助,这里有更有经验的Linux黑客。


请问您能解释一下 dict((os.path.split(dev)[-1], dev) 部分和 devices = devices or get_usb_devices() 吗? - Flame of udun
返回基于设备路径的字典,其中键是设备路径的基本名称(这是在编写代码时有用的附加信息)。 devices = devices or get_usb_devices() 大致相当于 devices = devices if devices != None else get_usb_devices(),意思是如果没有参数或参数为None,则应调用函数来查询设备。希望对您有所帮助。 - m.wasowski

5

我不得不修改@m.wasowski的代码,使其能在Python3.5.4上工作,如下所示。

def get_mount_points(devices=None):
    devices = devices or get_usb_devices()  # if devices are None: get_usb_devices
    output = check_output(['mount']).splitlines()
    output = [tmp.decode('UTF-8') for tmp in output]

    def is_usb(path):
        return any(dev in path for dev in devices)
    usb_info = (line for line in output if is_usb(line.split()[0]))
    return [(info.split()[0], info.split()[2]) for info in usb_info]

4
使用m.wasowski的代码时,可能会出现意外行为:
return [(info.split()[0], info.split()[2]) for info in usb_info]

如果您的USB设备名称中包含空格字符,则此部分代码可能会产生错误。我使用名为"USB DEVICE"的设备时遇到了这种行为。

info.split()[2]

当它是媒体/家庭/USB设备时,为我返回了媒体/家庭/USB。

我修改了那部分,所以找到了单词"type",并用这行替换了它:

#return [(info.split()[0], info.split()[2]) for info in usb_info]

fullInfo = []
for info in usb_info:
    print(info)
    mountURI = info.split()[0]
    usbURI = info.split()[2]
    print(info.split().__sizeof__())
    for x in range(3, info.split().__sizeof__()):
        if info.split()[x].__eq__("type"):
            for m in range(3, x):
                usbURI += " "+info.split()[m]
            break
    fullInfo.append([mountURI, usbURI])
return fullInfo

0

我不得不进一步修改@nick-sikrier和@m-wasowski的响应以处理LUKs加密设备。

def get_usb_devices():
    sdb_devices = map(os.path.realpath, glob('/sys/block/sd*'))
    usb_devices = (dev for dev in sdb_devices
                   if any(['usb' in dev.split('/')[5],
                           'usb' in dev.split('/')[6]]))
    return dict((os.path.basename(dev), dev) for dev in usb_devices)

def get_mount_points(
    devices = get_usb_devices()
    fullInfo = []
    for dev in devices:
        output = subprocess.check_output(['lsblk', '-lnpo', 'NAME,MOUNTPOINT', '/dev/' + dev]).splitlines()
    for mnt_point in output:
        mnt_point_split = mnt_point.split(' ', 1)
        if len(mnt_point_split) > 1 and mnt_point_split[1].strip():
            fullInfo.append([mnt_point_split[0], mnt_point_split[1]])
    return fullInfo

get_usb_devices() is returning an empty dict for me, even though ls /sys/block/ | grep "sd*" outputs sda and there's entries given by lsblk -lnpo NAME,MOUNTPOINT /dev/sda* - Drake P

0

通过在Python中执行简单的shell管道:

import subprocess
driver_name = "my_usb_stick"

path = subprocess.check_output("cat /proc/mounts | grep '"+driver_name+"' | awk '{print $2}'", shell=True)

path = path.decode('utf-8') # convert bytes in string

>>> "/media/user/my_usb_stick"

解释

  • /proc/mounts/ :是列出所有已挂载设备的文件
  • 第一列指定了已挂载的设备。
  • 第二列显示了挂载点。
  • 第三列告诉你文件系统类型。
  • 第四列告诉你它是以只读(ro)还是读写(rw)方式挂载的。
  • 第五和第六列是虚拟值,旨在匹配/etc/mtab中使用的格式。

更多细节请参见此答案:如何解释/proc/mounts?

  • grep 返回包含驱动程序名称的行

  • awk 返回第二列,也就是挂载点,也就是您的路径。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接