To eventually put into a bash script and/or Makefile, I'm wanting to find the device node path of the last inserted USB drive on a Debian system.
It will most likely be something like /dev/sdb
, but rather than assuming & hardcoding this, I'd like to find the device source programmatically, if possible.
I can see a list of mount points using findmnt
and spot the USB drive by eye in that list, but there doesn't seem to be a robust way to search using findmnt
unless you know either the USB drive's "target" or "source" field value exactly, (e.g. /media/user/Thumbdrive
) which we can't know dynamically:
findmnt --noheadings --output source --target /media/user/Thumbdrive
/dev/sdb1
Some guides I looked at online mentioned you could trawl the output of dmesg
to get information about the last inserted USB device, and that looks promising (because there's a sdb: sdb1
line, and entries are logged by time since boot), but how/what to pattern match for such output given it would probably be most sensible to look for entries after, say, usb-storage
first for context, and it could be a variable amount of lines before we get to the sdX: X
entry (as well as the possibility of being interleaved with other unrelated kernel messages)?
[58972.861628] usb 1-1: new high-speed USB device number 12 using xhci_hcd
[58973.017906] usb 1-1: New USB device found, idVendor=0930, idProduct=1400, bcdDevice= 1.00
[58973.017912] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[58973.017916] usb 1-1: Product: TOSHIBA USB DRV
[58973.017919] usb 1-1: Manufacturer: TOSHIBA
[58973.017921] usb 1-1: SerialNumber: 03A81B061C4C86
[58973.019758] usb-storage 1-1:1.0: USB Mass Storage device detected
[58973.020517] scsi host2: usb-storage 1-1:1.0
[58973.116352] [UFW BLOCK] IN=wlp1s0 OUT= MAC=...
[58974.118040] [UFW BLOCK] IN=wlp1s0 OUT= MAC=...
[58975.160865] scsi 2:0:0:0: Direct-Access TOSHIBA TOSHIBA USB DRV PMAP PQ: 0 ANSI: 4
[58975.161608] sd 2:0:0:0: Attached scsi generic sg1 type 0
[58975.162908] sd 2:0:0:0: [sdb] 60555264 512-byte logical blocks: (31.0 GB/28.9 GiB)
[58975.163588] sd 2:0:0:0: [sdb] Write Protect is off
[58975.163598] sd 2:0:0:0: [sdb] Mode Sense: 23 00 00 00
[58975.164252] sd 2:0:0:0: [sdb] No Caching mode page found
[58975.164264] sd 2:0:0:0: [sdb] Assuming drive cache: write through
[58975.181161] sdb: sdb1
[58975.196147] sd 2:0:0:0: [sdb] Attached SCSI removable disk
[58976.576602] [UFW BLOCK] IN=wlp1s0 OUT= MAC=...
For instance, this awk
line is a start, but it's not robust.
dmesg -t | awk '/^\s+sd\w:\s.*/ {print "/dev/"$2}' | tail -1
/dev/sdb1
Any ideas? Or better yet, is there a tool specifically for this job (preferably one that bundles with Debian by default) that I am yet to discover?
Thanks!
Update
To be more clear, I'm looking for a solution that can be invoked inside a bash script or Makefile (and most likely without superuser access beforehand), and which assumes a disk has been inserted before the script runs, so solutions that require creating files to monitor kernel info beforehand are maybe not desirable.
Also, if a drive has been inserted and then removed before the script runs, that will also need to be considered at eventual runtime--i.e. the best solution would know the current system state (or at least one as close as possible to current).
The bash script/Makefile is attempting to make it easier for the user to write a disk image to the USB drive (by guessing what the USB drive might be and suggesting that), so trying to reduce false positives and so on will be a consideration.
SUBSYSTEM=="block", ENV{DEVTYPE}=="disk", SUBSYSTEMS=="usb"
. ("singular" and "plural" have very different meaning in udev matching) See the man page of udev for more details regardingRUN
and%k
.