(Old answer, new answer further below)
Run a script or command to run whenever a usb drive gets connected
If, for whatever reasons, you do not want to use udev
rules or anything more complicated, then use the script below.
Simply running the script, with your command to run as argument, will do the job.
The script:
#!/usr/bin/env python3
import subprocess
import time
import sys
cmd = " ".join(sys.argv[1:])
def get_mountedlist():
return [(item.split()[0].replace("├─", "").replace("└─", ""),
item[item.find("/"):]) for item in subprocess.check_output(
["/bin/bash", "-c", "lsblk"]).decode("utf-8").split("\n") if "/" in item]
def identify(disk):
command = "find /dev/disk -ls | grep /"+disk
return "usb" in subprocess.check_output(["/bin/bash", "-c", command]).decode("utf-8")
mounted1 = get_mountedlist()
while True:
time.sleep(4)
mounted2 = get_mountedlist()
if [d for d in mounted2 if all([not d in mounted1, d != "/", identify(d[0]) == True])]:
subprocess.Popen(["/bin/bash", "-c", cmd])
mounted1 = mounted2
To use
- Copy the script into an empty file, save it as
run_usbactions.py
Test- run the script by (e.g.) the command:
python3 /path/to/run_usbactions.py <command_to_run> <optional_args>
In my test, I used e.g.:
python3 /path/to/run_usbactions.py gedit file
to open file
with gedit once a usb drive is connected.
If all works fine, add it to Startup Applications: Dash > Startup Applications > Add. Add the command:
python3 /path/to/run_usbactions.py <command_to_run> <optional_args>
Explanation
Once per four seconds, in the function get_mountedlist()
, the script reads the output of lsblk
.
In case additional partitions or devices are mounted, the output of (e.g.) the command:
find /dev/disk -ls | grep sdc1
will include the string usb
, and identify the mounted drive as a usb drive.
Looking at it now, I very well could replace it by a more "pythonic" way of doing it, instead of a system call, but since I copied it from an older script, I didn't (yet).
- subsequently, if the new drive is a usb, the command (+ possible args), as set in
" ".join(sys.argv[1:])
is run.
EDIT
(December 29, 2017)
Using pyudev
Since I "met" pyudev, I thought I should share the major simplification and clearer operation it brings. A simple script to perform any action on inserting a usb device then becomes:
#!/usr/bin/env python3
import pyudev
import subprocess
import sys
cmd = " ".join(sys.argv[1:])
monitor = pyudev.Monitor.from_netlink(pyudev.Context())
monitor.filter_by('block')
for device in iter(monitor.poll, None):
if all([
device['ACTION'] == "add", 'ID_FS_TYPE' in device,
device['ID_USB_DRIVER'] == "usb-storage",
]):
print("added", device.get('ID_FS_LABEL'))
subprocess.Popen(["/bin/bash", "-c", cmd])
Usage
Make sure pyudev
is installed:
sudo apt install python3-pyudev
Further instructions are exactly similar.