Linux中更好的脚本USB设备挂载方式

2024-05-12 17:21:32 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在为一个与用户提供的USB记忆棒交互的设备编写一个python模块。用户可以在设备USB插槽中插入USB记忆棒,设备将在无需用户干预的情况下将数据转储到记忆棒上。如果用户插入U盘时设备正在运行,那么我已经连接到D-Bus,并且已经完成了一个自动挂载程序。新问题是,如果在设备断电时插入了斗杆怎么办?我没有得到D总线插入事件,或任何相关的信息块的记忆棒后,设备上电。

我已经找到了一种方法来派生设备节点(/dev/sd?)通过调用/proc扫描USB设备:

ls /proc/scsi/usb-storage

如果对该文件夹中的每个文件进行分类,则会显示scsi设备信息。

然后从usb存储记录中获取Vendor、Product和Serial Number字段,生成一个标识符字符串,然后在其中使用

ll /dev/disc/by-id/usb_[vendor]_[product][序列号]-0:0

所以我可以通过分析结果得到相对路径

../../sdc

然后,我可以安装U盘。

这是一个很麻烦的过程,几乎都是基于文本的,并且当有人引入一个奇怪的字符或非标准序列号字符串时,它就准备好了。它可以和我所有的2个USB记忆棒一起工作。我曾试图映射/var/log/messages的输出,但最后还是进行了文本比较。lsusb、fdisk、udevinfo、lsmod和其他文件的输出只显示所需数据的一半。

我的问题是:在没有D-Bus消息的情况下,如何在不需要用户干预的情况下确定分配给USB存储棒的/dev设备,或者事先知道插入设备的详细信息?

谢谢,对这本小说感到抱歉。


Tags: 文件数据字符串用户dev文本信息情况
3条回答

这似乎结合了ephimient采用的/proc/partitions/sys/class/block方法。

#!/usr/bin/python
import os
partitionsFile = open("/proc/partitions")
lines = partitionsFile.readlines()[2:]#Skips the header lines
for line in lines:
    words = [x.strip() for x in line.split()]
    minorNumber = int(words[1])
    deviceName = words[3]
    if minorNumber % 16 == 0:
        path = "/sys/class/block/" + deviceName
        if os.path.islink(path):
            if os.path.realpath(path).find("/usb") > 0:
                print "/dev/%s" % deviceName

我不知道这是多么便携或可靠,但它为我的U盘工作。当然find("/usb")可以变成更严格的正则表达式。做mod 16也可能不是找到磁盘本身并过滤掉分区的最佳方法,但是到目前为止,它对我是有效的。

我不完全确定这个有多轻便。此外,这些信息可能也可以通过D-Bus从udisksHAL获得,但这两个信息都不在我的系统中,所以我无法尝试。不管怎样,这里似乎是相当准确的:

$ for i in /sys/class/block/*; do
>     /sbin/udevadm info -a -p $i | grep -qx '    SUBSYSTEMS=="usb"' &&
>     echo ${i##*/}
> done
sde
sdf
sdg
sdh
sdi
sdj
sdj1
$ cd /sys/class/block/
$ for i in *; do [[ $(cd $i; pwd -P) = */usb*/* ]] && echo $i; done
sde
sdf
sdg
sdh
sdi
sdj
sdj1

looking at this thread讲述了ubuntu如何处理nautilus之后,我找到了一些建议,并决定通过shell命令访问udisk。

您需要的是大容量存储设备类。把设备文件给它。ie:/dev/sdb 然后,您可以执行d.mount()和d.mount_点,以获取它的安装位置。

之后也是一个类,用于查找许多相同的USB设备,以控制安装、卸载和弹出一大串具有相同标签的设备。 (如果运行时没有参数,则它会将此应用于所有SD设备。对于“自动挂载所有内容”脚本来说可能很方便

import re
import subprocess

#used as a quick way to handle shell commands
def getFromShell_raw(command):
    p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    return p.stdout.readlines()

def getFromShell(command):
    result = getFromShell_raw(command)
    for i in range(len(result)):       
        result[i] = result[i].strip() # strip out white space
    return result



class Mass_storage_device(object):
    def __init__(self, device_file):
       self.device_file = device_file
       self.mount_point = None

    def as_string(self):
        return "%s -> %s" % (self.device_file, self.mount_point)

    """ check if we are already mounted"""
    def is_mounted(self):
        result = getFromShell('mount | grep %s' % self.device_file)
        if result:
            dev, on, self.mount_point, null = result[0].split(' ', 3)
            return True
        return False

    """ If not mounted, attempt to mount """
    def mount(self):
        if not self.is_mounted():
            result = getFromShell('udisks --mount %s' % self.device_file)[0] #print result
            if re.match('^Mounted',result): 
                mounted, dev, at, self.mount_point = result.split(' ')

        return self.mount_point

    def unmount(self):
        if self.is_mounted():
            result = getFromShell('udisks --unmount %s' % self.device_file) #print result
            self.mount_point=None

    def eject(self):
        if self.is_mounted():
            self.unmount()
        result = getFromShell('udisks --eject %s' % self.device_file) #print result
        self.mount_point=None


class Mass_storage_management(object):
    def __init__(self, label=None):
        self.label = label
        self.devices = [] 
        self.devices_with_label(label=label)

    def refresh(self):
        self.devices_with_label(self.label)

    """ Uses udisks to retrieve a raw list of all the /dev/sd* devices """
    def get_sd_list(self):
        devices = []
        for d in getFromShell('udisks --enumerate-device-files'):
            if re.match('^/dev/sd.$',d): 
                devices.append(Mass_storage_device(device_file=d))
        return devices


    """ takes a list of devices and uses udisks --show-info 
    to find their labels, then returns a filtered list"""
    def devices_with_label(self, label=None):
        self.devices = []
        for d in self.get_sd_list():
            if label is None:
                self.devices.append(d)
            else:
                match_string = 'label:\s+%s' % (label)
                for info in getFromShell('udisks --show-info %s' % d.device_file):
                    if re.match(match_string,info): self.devices.append(d)
        return self

    def as_string(self):
        string = ""
        for d in self.devices:
            string+=d.as_string()+'\n'
        return string

    def mount_all(self): 
        for d in self.devices: d.mount()

    def unmount_all(self): 
        for d in self.devices: d.unmount()

    def eject_all(self): 
        for d in self.devices: d.eject()
        self.devices = []



if __name__ == '__main__':
    name = 'my devices'
    m = Mass_storage_management(name)
    print m.as_string()

    print "mounting"
    m.mount_all()
    print m.as_string()

    print "un mounting"
    m.unmount_all()
    print m.as_string()

    print "ejecting"
    m.eject_all()
    print m.as_string()

相关问题 更多 >