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
How to Sort Pandas Dataframe from One Column
Sending a Password Over Ssh or Scp with Subprocess.Popen
Ignore Case in Glob() on Linux
Python: Interplay Between Lib/Site-Packages/Site.Py and Lib/Site.Py
Python: What Are the Nearest Linux and Osx Equivalents of Winsound.Beep
Capturing Output of Python Script Run Inside a Docker Container
Create Single Python Executable Module
Using Pyinotify to Watch for File Creation, But Waiting for It to Be Completely Written to Disk
Proxies With Python 'Requests' Module
What Is a Clean "Pythonic" Way to Implement Multiple Constructors
How to Split a Huge CSV File Based on Content of First Column
Python Multiprocessing Memory Usage
How to Properly Write to Fifos in Python
Cannot Bind Numpad Minus Key on Linux with Tkinter
Process Dies, If It Is Run via Paramiko Ssh Session and with "&" in the End