Better way to script USB device mount in Linux

12,230

Solution 1

This seems to work combining /proc/partitions and the /sys/class/block approach ephimient took.

#!/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

I'm not sure how portable or reliable this is, but it works for my USB stick. Of course find("/usb") could be made into a more rigorous regular expression. Doing mod 16 may also not be the best approach to find the disk itself and filter out the partitions, but it works for me so far.

Solution 2

I'm not entirely certain how portable this is. Also, this information would presumably also be available over D-Bus from udisks or HAL but neither of those is present on my system so I can't try. It seems to be reasonably accurate here regardless:

$ 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
Share:
12,230
Therealstubot
Author by

Therealstubot

Nonya.

Updated on June 08, 2022

Comments

  • Therealstubot
    Therealstubot almost 2 years

    I'm writing a python module for a device that interacts with a user supplied USB memory stick. The user can insert a USB memory stick in the device USB slot, and the device will dump data onto the memory stick without user intervention. If the device is running when the user inserts the USB stick, I have hooked into D-Bus and have an auto mount routine all worked out. The new issue is, what if the stick is inserted while the device is powered off? I get no D-Bus insertion event, or any the associated nuggets of information about the memory stick after the device is powered on.

    I have worked out a way to derive the device node ( /dev/sd? ) from scanning the USB devices in /proc, by calling:

    ls /proc/scsi/usb-storage

    this gives the scsi device info if you cat each of the files in that folder.

    I then take the Vendor, Product, and Serial Number fields from the usb-storage records, generate an identifier string that I then use in

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

    So I can parse through the result to get the relative path

    ../../sdc

    Then, I can mount the USB stick.

    This is a cumbersome procedure, pretty much all text based, and ready for bugs when someone introduces a weird character, or non-standard serial number string. It works with all 2 of the USB memory sticks I own. I have tried to map output from /var/log/messages but that ends up being text comparisons as well. Output from lsusb, fdisk, udevinfo, lsmod, and others only show half of the required data.

    My question: how do I determine, in the absence of a D-Bus message, the /dev device assigned to a USB memory stick without user intervention, or knowing in advance the specifics of the inserted device?

    Thanks, sorry about the novel.

  • Therealstubot
    Therealstubot about 14 years
    I actually adopted a simpler method. I look in /dev/disk/by-id/usb--part Each of the entries in there are links to the /dev devices. A quick call to os.path.realpath gets the linked device.