Apparently it can be done more simply with udevadm
, and I've just found out how.
To get the DEVNAME
from udevadm
you need only do:
udevadm info -rq name $PATH
For instance, if you wanted to know the /dev
name for /sys/dev/char/5:1
you'd do:
udevadm info -rq name /sys/dev/char/5:1
OUTPUT
/dev/console
The -r
option is to specify a --root
ed path - without it the result above would read only console
. The -q
option specifies a database --query
and it takes the operand name
here - because we want the DEVNAME
.
A very simple means of finding the path to a char and/or block device given only the major:minor numbers might look like:
mmdev() for d in /sys/dev/[cb]*/$1:$2
do [ -e "$d" ] || return
printf %c:%s: "${d#/*/*/}" "${d##*/}"
udevadm info -rq name "$d"
done
So running:
mmdev 8 0
prints...
b:8:0:/dev/sda
Here's the first one I wrote.
majminpath() {
set -- ${1##*[!0-9]*} ${2##*[!0-9]*}
udevadm info --export-db |
sed 's|^[^=]*DEVNAME=||
\|^[^/]|!h;/MAJOR=/N
\|='"$1\n.*=${2?}"'$|!d;g'
}
This just scans udevadm info --export-db
output for the matching numbers. The output looks like:
P: /devices/virtual/vc/vcsa4
N: vcsa4
E: DEVNAME=/dev/vcsa4
E: DEVPATH=/devices/virtual/vc/vcsa4
E: MAJOR=7
E: MINOR=132
E: SUBSYSTEM=vc
P: /devices/virtual/vc/vcsa5
N: vcsa5
E: DEVNAME=/dev/vcsa5
E: DEVPATH=/devices/virtual/vc/vcsa5
E: MAJOR=7
E: MINOR=133
E: SUBSYSTEM=vc
#...and so on
The workflow is like:
attempt to strip the [^=]*DEVNAME=
string from the head of each line
if a line does not have a first character or its first character is /
copy that line over h
old space
if a line matches MAJOR=
append N
ext input line to pattern space
if there are 2 lines in pattern space that match =$1\n.*=$2$
then copy h
old space over pattern space and auto-print; else delete pattern space
So if I do:
majminpath 7 133 ; majminpath 8 0 ; majminpath 8 1
OUTPUT
/dev/vcsa5
/dev/sda
/dev/sda1
But, as @xae points out, block/char type devices can share maj:min combinations, and so this might possibly print more than one path per call.