Лучший способ сценария установки устройства USB в Linux

Я пишу модуль python для устройства, которое взаимодействует с USB-накопителем USB. Пользователь может вставить USB-накопитель в слот USB устройства, и устройство будет выгружать данные на карту памяти без вмешательства пользователя. Если устройство работает, когда пользователь вставляет USB-накопитель, я подключился к D-Bus и автоматически выполнил процедуру автоматического монтирования. Новая проблема заключается в том, что, если палка вставлена ​​при выключенном устройстве? Я не получаю событие вставки D-Bus или любые связанные с ним самородки информации о карте памяти после включения устройства.

Я разработал способ вывода узла устройства (/ dev / sd?) Из сканирования USB-устройств в / proc, вызывая:

ls /proc/scsi/usb-storage

это дает информацию об устройстве scsi, если вы каталите каждый из файлов в этой папке.

Затем я беру поля «Поставщик», «Продукт» и «Серийный номер» из записей хранилища usb, генерирует строку идентификатора, которую я затем использую в

ll /dev/disc/by-id/usb_[vendor] _[product] _[serial_number]-0:0

Поэтому я могу проанализировать результат, чтобы получить относительный путь

../../sdc

Затем я смогу установить USB-накопитель.

Это громоздкая процедура, почти все текстовые и готовые к ошибкам, когда кто-то вводит странный символ или нестандартную строку серийного номера. Он работает со всеми 2 USB-накопителями USB, которыми я владею. Я попытался отобразить вывод из / var / log / messages, но в итоге это тоже текстовые сравнения. Выходные данные из lsusb, fdisk, udevinfo, lsmod и других показывают только половину требуемых данных.

Мой вопрос: как определить, при отсутствии сообщения D-Bus, устройство / dev, назначенное на USB-накопитель без вмешательства пользователя, или заранее знать специфику вставленного устройства?

Спасибо, извините за роман.

  • кроссплатформенный модуль usb для python?
  • pyusb: невозможно настроить конфигурацию
  • Отправка шестнадцатеричного кода с помощью python
  • Библиотека Pylibftdi не работает (серийный режим, UM232H)
  • Как я могу прослушивать события «usb device insert» в Linux, на Python?
  • Могу ли я управлять архитектурой (32 бит против 64 бит) при создании исполняемого файла pyinstaller?
  • Использование драйверов FTDI D2XX с Python из Raspberry Pi на платформе raspbian soft-float
  • Простой способ запросить информацию о подключенных USB-устройствах в Python?
  • 4 Solutions collect form web for “Лучший способ сценария установки устройства USB в Linux”

    Кажется, что это работает, комбинируя /proc/partitions и efimient подходом /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 

    Я не уверен, насколько портативен или надежный, но он работает для моего USB-накопителя. Разумеется, find("/usb") можно было бы более строгое регулярное выражение. Выполнение mod 16 также не может быть лучшим подходом для поиска самого диска и отфильтровывания разделов, но он работает для меня до сих пор.

    Я не совсем уверен, насколько это переносится. Кроме того, эта информация предположительно также будет доступна через D-Bus от udisks или HAL, но ни одна из них не присутствует в моей системе, поэтому я не могу попробовать. Это, кажется, достаточно точно здесь, независимо от того,

     $ for i in / sys / class / block / *;  делать
     > / sbin / udevadm info -a -p $ i |  grep -qx 'SUBSYSTEMS == "usb"' &&
     > echo $ {i ## * /}
     > сделано
     СДУ
     SDF
     SDG
     SDH
     СОИ
     SDJ
     sdj1
     $ cd / sys / class / block /
     $ for i in *;  do [[$ (cd $ i; pwd -P) = * / usb * / *]] && echo $ i;  сделанный
     СДУ
     SDF
     SDG
     SDH
     СОИ
     SDJ
     sdj1
    

    Посмотрев эту тему о том, что делает ubuntu с nautilus, я нашел несколько рекомендаций и решил пойти с доступом к udisks через команды оболочки.

    Класс Mass Storage – это то, что вы хотите. Просто дайте ему файл устройства. т.е.: / dev / sdb, вы можете затем выполнить d.mount () и d.mount_point, чтобы получить место, где он был установлен.

    После этого это также класс для поиска многих идентичных 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() 

    почему бы вам просто не использовать правило udev? мне пришлось иметь дело с подобной ситуацией, и моим решением было создать файл в /etc/udev/rules.d, содержащий следующее правило:

     SUBSYSTEMS=="scsi", KERNEL=="sd[bh]1", RUN+="/bin/mount -o umask=000 /dev/%k /media/usbdrive" 

    одно предположение здесь состоит в том, что никто никогда не вставляет более одного USB-накопителя вовремя. однако у него есть преимущество, что я знаю заранее, где будет установлен палочка (/ media / usbdrive).

    вы можете с уверенностью уточнить это, чтобы сделать его более умным, но лично мне никогда не приходилось его менять, и он по-прежнему работает на нескольких компьютерах.

    однако, как я понимаю, вы хотите, чтобы вас предупреждали, когда вставлена ​​палка, и, возможно, эта стратегия дает вам некоторые проблемы с этой стороны, я не знаю, не исследовал …

    Python - лучший язык программирования в мире.