Python 在Linux中编写USB设备装载脚本的更好方法

Python 在Linux中编写USB设备装载脚本的更好方法,python,linux,usb,Python,Linux,Usb,我正在为一个与用户提供的USB记忆棒交互的设备编写python模块。用户可以将USB记忆棒插入设备USB插槽,设备将在无需用户干预的情况下将数据转储到记忆棒上。如果当用户插入U盘时设备正在运行,我已经连接到D-Bus,并有了一个自动安装程序。新的问题是,如果在设备断电时插入斗杆会怎么样?在设备通电后,我没有收到任何D-Bus插入事件,也没有收到任何有关记忆棒的相关信息 我已经找到了一种方法,通过调用以下命令,通过扫描/proc中的USB设备来派生设备节点(/dev/sd?): ls/proc/s

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

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

ls/proc/scsi/usb存储

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

然后从usb存储记录中获取供应商、产品和序列号字段,生成一个标识符字符串,然后在中使用

ll/dev/disc/by id/usb\u[供应商]
\u[产品]
\u[序列号]-0:0

所以我可以通过解析结果来获得相对路径

。/../sdc

然后,我可以安装U盘

这是一个很麻烦的过程,几乎都是基于文本的,当有人引入一个奇怪的字符或非标准的序列号字符串时,它随时可能出现错误。它适用于我所有的2个USB记忆棒。我曾尝试映射/var/log/messages的输出,但结果也是文本比较。lsusb、fdisk、udevinfo、lsmod等的输出仅显示所需数据的一半

我的问题:在没有D-Bus消息的情况下,我如何确定分配给USB记忆棒的/dev设备,而无需用户干预,或者事先知道插入设备的细节


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

我不太确定它的便携性。此外,这些信息可能也可以从或通过D-Bus获得,但我的系统中没有这两个信息,因此我无法尝试。不管怎样,这似乎是相当准确的:

$ 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 $in/sys/class/block/*中的i;做 >/sbin/udevadm info-a-p$i | grep-qx'子系统==“usb”'&& >echo${i##*/} >完成 sde 自卫队 可持续发展目标 sdh sdi 圣日耳曼 sdj1 $cd/sys/class/block/ 美元兑换1英镑*;do[[$(cd$i;pwd-P)=*/usb*/*]&&echo$i;完成 sde 自卫队 可持续发展目标 sdh sdi 圣日耳曼 sdj1
这似乎可以将
/proc/partitions
和Ephiment采用的
/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也可能不是查找磁盘本身和过滤分区的最佳方法,但到目前为止,它对我很有效。

在了解了ubuntu对nautilus的作用后,我找到了一些建议,并决定通过shell命令访问UDisk

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

之后,该类还用于查找许多相同的USB设备,以控制安装、取消安装和弹出具有相同标签的大量设备列表。 (如果您在没有参数的情况下运行is,它会将此应用于所有SD设备。对于“仅自动装载所有内容”脚本来说可能很方便


为什么不直接使用udev规则呢?我必须处理类似的情况,我的解决方案是在/etc/udev/rules.d中创建一个包含以下规则的文件:

SUBSYSTEMS=="scsi", KERNEL=="sd[b-h]1", RUN+="/bin/mount -o umask=000 /dev/%k /media/usbdrive"
这里的一个假设是,没有人一次插入超过一个U盘。然而,它的优点是我提前知道U盘将安装在哪里(/media/usbdrive)

你当然可以把它做得更聪明一些,但就我个人而言,我从来没有改变过它,而且它在好几台计算机上仍然可以工作


然而,据我所知,当插入一根棍子时,您希望以某种方式得到提醒,也许这一策略在这方面给您带来了一些麻烦,我不知道,没有调查…

我认为最简单的方法是使用lsblk:

lsblk -d -o NAME,TRAN | grep usb

实际上,我采用了一种更简单的方法。我查看/dev/disk/by id/usb——其中的每个条目都有指向/dev设备的链接。快速调用os.path.realpath可以获得链接的设备。
lsblk -d -o NAME,TRAN | grep usb