通过主/次数字对获取设备节点

通过主/次数字对获取设备节点

下面的每个设备节点/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选项是指定一个--rooted 路径 - 如果没有它,上面的结果将是只读的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

该模式的简单形式已经在输出中提供了有关所需设备的信息,但是也可以进行额外的过滤以仅提取一个特定字符串。

相关内容