メジャー/マイナー番号のペアでデバイスノードを取得する

メジャー/マイナー番号のペアでデバイスノードを取得する

以下の各デバイスノード/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データベースを指定します。なぜなら私たちが欲しいからです。--querynameDEVNAME

メジャー:マイナー数だけが与えられた場合、文字および/またはブロックデバイスへのパスを見つけるための非常に簡単な方法は次のとおりです。

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

  • パターンスペースに一致する行が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同じタイプ、プライマリデバイス、およびセカンダリデバイスを持つ1つ以上のファイルを見つけるには、次のことを実行できます(使用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以下を見ると、 major:minor からカーネルに移動できます。

$ 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

udevmikeservが示すように、データベースからこの情報を取得することもできます。

答え4

/procLinuxでは、仮想ファイルシステム内の特定のファイルを利用できます。

$ 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

このパターンの単純な形式は、すでに出力に必要なデバイスに関する情報を提供しますが、特定の文字列のみを抽出するために追加のフィルタリングを実行することもできます。

関連情報