Better Way to Script Usb Device Mount in Linux

Better way to script USB device mount in Linux

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.

Executing scripts that read from most recent USB udev plugged in device

The run-parts bit is a tip-off...you can create a file /etc/usbmount/mount.d/50_copydata

Something like this:

#!/bin/bash
set -u
[[ -f "${UM_MOUNTPOINT}/data.txt" ]] && cat "${UM_MOUNTPOINT}/data.txt" > /tmp/output.txt

usbmount will set $UM_MOUNTPOINT to i.e. /media/usb0. I use set -u to make sure it only executes if $UM_MOUNTPOINT is set.

I assume you are going to filter the data - if you are only going to cat the file you might as well use cp.

Remember to make the file executable:

chmod +x /etc/usbmount/mount.d/50_copydata

Unplug and re-plug your device(s) to test. Hope this helps!

Auto mount usb drive from udev rules and shell script

I think I identified the problem.
Apparently, udev uses a specific namespace, indeed I can see the mount point by printing the content of /proc/<daemon_pid>/mountinfo where is the pid of the systemd-udevd service.

$ cat /proc/240/mountinfo
[...]
228 43 8:17 / /media/usb/test rw,relatime - vfat /dev/sdb1 rw,fmask=0022,dmask=0022,codepage=437,iocharset=ascii,shortname=mixed,utf8,errors=remount-ro

$ df
Sys. de fichiers blocs de 1K Utilisé Disponible Uti% Monté sur
udev 1975740 0 1975740 0% /dev
tmpfs 397376 5916 391460 2% /run
/dev/sda2 75733088 69473400 2389532 97% /
tmpfs 1986868 111860 1875008 6% /dev/shm
tmpfs 5120 4 5116 1% /run/lock
tmpfs 1986868 0 1986868 0% /sys/fs/cgroup
tmpfs 397372 28 397344 1% /run/user/112
tmpfs 397372 24 397348 1% /run/user/1001

So the solution should be to force udev to execute the script in root userspace.
I tried the solution I found here https://unix.stackexchange.com/questions/330094/udev-rule-to-mount-disk-does-not-work

However, my system doesn't have a /usr/lib/systemd/system/systemd-udevd.service file. I created a file /etc/systemd/system/systemd-udevd.service with content

MountFlags=shared 

But with this solution, my system is not able to boot anymore.

Does someone know how I could either execute the script in root userspace or share the mount point with users?

PS : I precise I'm running a 64 bits Debian 9

Solved edit : Finally the file was located at /lib/systemd/system/systemd-udevd.service. I duplicated it in /etc/systemd/system/systemd-udevd.service
and changed MountFlags=slave to MountFlags=shared and now it works perfectly :)

How to execute a shellscript when I plug-in a USB-device

If you want to run the script on a specific device, you can use the vendor and product ids

  • In /etc/udev/rules.d/test.rules:

    ATTRS{idVendor}=="152d", ATTRS{idProduct}=="2329", RUN+="/tmp/test.sh"
  • in test.sh:

    #! /bin/sh

    env >>/tmp/test.log
    file "/sys${DEVPATH}" >>/tmp/test.log

    if [ "${ACTION}" = add -a -d "/sys${DEVPATH}" ]; then
    echo "add ${DEVPATH}" >>/tmp/test.log
    fi

With env, you can see what environment is set from udev and with file, you will discover the file type.

The concrete attributes for your device can be discovered with lsusb

lsusb

gives

...

Bus 001 Device 016: ID 152d:2329 JMicron Technology Corp. / JMicron USA Technology Corp. JM20329 SATA Bridge

...

Auto mounting USB on a yocto linux embedded project with udev

After much tinkering and reading information on the web I found a solution that worked on my system.

I had to insert a systemd service after the udev rule and then a bash script called from the service that did the heavy lifting.

So a thanks goes out to Mike Blackwell for his excellent answer to a similar question over on stackexchange. https://serverfault.com/a/767079

I used his suggestion with a few tweeks for my own system and it worked perfectly.

output mountpoint on (usb)device detection

The problem was a timing issue and can be solved by adding (for me) minimum sleep time of 0.2 sec between detecting and executing the command


EXCLUDE_DEVICE_1="5F92-0F71"
EXCLUDE_DEVICE_2="6fd9f710-f897-4b13-a521-70e184f669f3"
LOG_FILE=/home/user/Documents/log.txt

exec > >(tee -a $LOG_FILE)
exec 2>&1

inotifywait -m --exclude "($EXCLUDE_DEVICE_1|$EXCLUDE_DEVICE_2)" -e create --format '%f' /dev/disk/by-uuid/ \
| while read UUID
do
echo "new device found with uuid: $UUID"
sleep 0.2
lsblk --noheadings --output MOUNTPOINT /dev/disk/by-uuid/$UUID
done


Related Topics



Leave a reply



Submit