下面的每个设备节点/dev
都有其自己的主/副号码对。我知道我们可以通过的方式从设备节点检索这对数字stat
,如下所示:
stat -c 'major: %t minor: %T' <file>
或者,ls -l
也显示这些数字。
但是,如何通过给定的主号和副号获得设备节点?我知道的唯一方法是某种ls -l
+ awk
技巧,但我真的希望有更好的解决方案。
下面的每个设备节点/dev
都有其自己的主/副号码对。我知道我们可以通过的方式从设备节点检索这对数字stat
,如下所示:
stat -c 'major: %t minor: %T' <file>
或者,ls -l
也显示这些数字。
但是,如何通过给定的主号和副号获得设备节点?我知道的唯一方法是某种ls -l
+ awk
技巧,但我真的希望有更好的解决方案。
Answers:
我发现了使用sys伪文件系统的一种更简单的方法,在/ sys / dev,按类型依次按顺序排列设备,然后按主/次要顺序排列,文件uevent包含设备名称和许多其他信息。
例如
for file in $(find /sys/dev/ -name 7:0); do
source ${file}/uevent; echo $DEVNAME;
done;
回声
loop0
vcs
注意:这已在Debian Wheezy中进行了测试
for file in $(ls /sys/dev/block/ ); do source /sys/dev/block/${file}/uevent; if [ "$DEVNAME" == "sda1" ] ; then echo ${file}; fi done;
不明白你的意思。
mknod foo b 8 0
将创建称为foo
块设备的设备文件,主文件号为8,次要文件号为0。如果要查找其中一个或任何文件/dev
,具有主文件号和次要文件类型,可以执行(使用zsh
):
对于块设备8:0
:
$ zmodload zsh/stat
$ ls -ld /dev/**/*(-D%be:'zstat -H s $REPLY && (($s[rdev] == 8<<8+0))':)
lrwxrwxrwx 1 root root 6 Aug 23 05:28 /dev/block/8:0 -> ../sda
lrwxrwxrwx 1 root root 9 Aug 23 05:28 /dev/disk/by-id/ata-KINGSTON_SNV455S234GB_07MA10014418 -> ../../sda
brw-rw---- 1 root disk 8, 0 Aug 23 05:28 /dev/sda
对于char设备226:0
:
$ ls -ld /dev/**/*(-D%ce:'zstat -H s $REPLY && (($s[rdev] == 226<<8+0))':)
lrwxrwxrwx 1 root root 12 Aug 23 05:28 /dev/char/226:0 -> ../dri/card0
crw-rw----+ 1 root video 226, 0 Aug 23 05:28 /dev/dri/card0
请注意,任何内容都可以在中创建文件/dev
。在过去,这是一个在其中创建静态文件的脚本。在某些时候,您甚至有一个特殊的文件系统àla /proc
。
在现代版本的Linux上,它通常udev
基于内核的输入。
它为基本设备文件选择的名称基于DEVNAME
内核提供的名称。udev
规则可能会改变但通常不会改变,udev
为方便起见,有些规则会添加更多符号链接(例如/dev/disk/by...
那些符号链接)。
您可以DEVNAME
查看以下内容,从major:minor转到kernel 。
$ sed -n 's/^DEVNAME=//p' /sys/dev/block/8:0/uevent
sda
$ sed -n 's/^DEVNAME=//p' /sys/dev/char/226:0/uevent
dri/card0
您还可以从udev
数据库中获取该信息,如mikeserv所示。
显然,使用可以更简单地完成操作udevadm
,而我刚刚发现了操作方法。
为了得到DEVNAME
从udevadm
你只需要做到:
udevadm info -rq name $PATH
例如,如果您想知道自己的/dev
名字,/sys/dev/char/5:1
请执行以下操作:
udevadm info -rq name /sys/dev/char/5:1
/dev/console
该-r
选项是指定一个--root
编辑路径-如果没有它,结果只以上会读console
。该-q
选项指定一个数据库--query
,并在name
此处使用操作数-因为我们要使用DEVNAME
。
仅给定main:minor数字,一种查找char和/或block设备路径的非常简单的方法可能类似于:
mmdev() for d in /sys/dev/[cb]*/$1:$2
do [ -e "$d" ] || return
printf %c:%s: "${d#/*/*/}" "${d##*/}"
udevadm info -rq name "$d"
done
运行:
mmdev 8 0
打印...
b:8:0:/dev/sda
这是我写的第一个。
majminpath() {
set -- ${1##*[!0-9]*} ${2##*[!0-9]*}
udevadm info --export-db |
sed 's|^[^=]*DEVNAME=||
\|^[^/]|!h;/MAJOR=/N
\|='"$1\n.*=${2?}"'$|!d;g'
}
这只是扫描udevadm info --export-db
输出以查找匹配的数字。输出如下:
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
工作流程如下:
尝试[^=]*DEVNAME=
从每行的开头剥离字符串
如果一行没有第一个字符或第一个字符是/
在h
旧空间上复制该行
如果一行匹配,则将ext输入行MAJOR=
追加N
到模式空间
如果图案空间中有两行匹配,=$1\n.*=$2$
则将h
旧空间复制到图案空间并自动打印;否则删除模式空间
所以,如果我这样做:
majminpath 7 133 ; majminpath 8 0 ; majminpath 8 1
/dev/vcsa5
/dev/sda
/dev/sda1
但是,正如@xae指出的那样,块/字符类型的设备可以共享maj:min组合,因此每个调用可能会打印多个路径。
las,/sys/dev
仅在2.6.27以后才将层次结构添加到内核(请参阅针对内核代码库的相关提交),因此我们需要一种“分叉的”方法。
让$M
与$m
,分别是我们的设备文件的主要和次要号码。
正如其他人所建议的那样,最简单的方法是sysfs
通过直接追逐$M:$m
在该文件夹下命名的文件来释放“虚拟”文件系统的功能/sys/dev
(如果我们不知道我们的设备是否是字符,则可以预期有多个文件,或基于块的uevent
文件),然后获取文件(在子外壳中,以防止命名空间污染):
for file in $(find /sys/dev/ -name $M:$m)
do
(
source ${file}/uevent
echo $DEVNAME
)
done
为了简单起见,让我们假设我们的文件是一个块设备(类似的方法适用于字符设备)。我们将通过检查(在该文件夹下面)每个名称恰好为的文件的内容来在$M:$m
整个/sys/block
层次结构中搜索字符串dev
。如果/sys/block/<...>/<DEV>/dev
是这样的文件之一,那么DEV
必然是我们设备的名称:
dirname "$(find "/sys/block" -name dev | xargs -r grep -l ^$M:$m$)"
在Linux上,可以利用/proc
虚拟文件系统中的某些文件。
$ grep '8[[:blank:]]\+1[[:blank:]]\+' /proc/partitions
8 1 29309568 sda1
$ grep '8:1[[:blank:]]' /proc/self/mountinfo
28 0 8:1 / / rw,relatime shared:1 - ext4 /dev/sda1 rw,data=ordered
模式的简单形式已经在输出中提供了有关所需设备的信息,但是也可以进行附加过滤以仅提取一个特定的字符串。
有一个库函数: makedev()
#include <sys/sysmacros.h>
dev_t makedev(unsigned int maj, unsigned int min);
给定主要和次要设备ID,makedev()将这些ID组合起来以生成设备ID,并将其作为函数结果返回。
有关更多详细信息,请访问:http : //man7.org/linux/man-pages/man3/major.3.html