下面的每个设备节点/dev
都有自己的主/次编号对。我知道我们可以通过stat
以下方式从设备节点检索这对数字:
stat -c 'major: %t minor: %T' <file>
或者,ls -l
也显示这些数字。
但是我们如何通过给定的主设备号和次设备号来获取设备节点呢?我知道的唯一方法是某种ls -l
+awk
技巧,但我真的希望有更好的解决方案。
答案1
我发现了一种更简单的方法,使用系统伪文件系统,位于/系统/开发您已按类型排序设备,然后按主要/次要、文件排序事件包含设备名称和一堆其他信息。
例如,
for file in $(find /sys/dev/ -name 7:0); do
source ${file}/uevent; echo $DEVNAME;
done;
回声,
loop0
vcs
注意:这是在 Debian Wheezy 中测试的
答案2
显然可以用 更简单地完成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
ed 路径 - 如果没有它,上面的结果将是只读的console
。该-q
选项指定一个数据库--query
,它在此处接受操作数name
- 因为我们想要DEVNAME
.
仅给出主要:次要数字来查找字符和/或块设备的路径的一种非常简单的方法可能如下所示:
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
旧空间如果一行匹配
MAJOR=
追加N
将ext 输入行如果模式空间中有 2 行匹配,
=$1\n.*=$2$
则将h
旧空间复制到模式空间并自动打印;否则删除模式空间
所以如果我这样做:
majminpath 7 133 ; majminpath 8 0 ; majminpath 8 1
输出
/dev/vcsa5
/dev/sda
/dev/sda1
但是,正如 @xae 指出的那样,块/字符类型设备可以共享 maj:min 组合,因此每次调用可能会打印多个路径。
答案3
不明白你的意思。
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
对于字符设备
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
.在很早的时候,它是一个在其中创建静态文件的脚本。在某些时候,您甚至有一个特殊的文件系统/proc
。
在现代版本的 Linux 上,通常是udev
基于来自内核的输入。
它为基本设备文件选择的名称基于DEVNAME
内核提供的名称。udev
规则可能会改变这一点,但通常不会改变,并且某些udev
规则会添加更多符号链接以方便使用(例如/dev/disk/by...
)。
DEVNAME
您可以通过查看以下内容从主要:次要转到内核:
$ 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 所示。
答案4
在 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
该模式的简单形式已经在输出中提供了有关所需设备的信息,但是也可以进行额外的过滤以仅提取一个特定字符串。