Büyük / küçük sayılar çifti ile cihaz düğümünü alın


12

Altındaki her aygıt düğümü /devkendi ana / küçük sayı çiftine sahiptir. Bu numarayı cihaz düğümünden şu şekilde alabileceğimizi biliyorum, şöyle stat:

stat -c 'major: %t minor: %T' <file>

Veya ls -lbu sayıları da gösterir.

Ancak büyük ve küçük sayılarla cihaz düğümlerini nasıl alabiliriz? Farkında olduğum tek yol bir çeşit ls -l+ awknumara, ama umarım daha iyi bir çözüm vardır.


@mikeserv, evet Bazı cihazların bu numaraları paylaşabileceğini biliyorum, bu yüzden ilk sorumda "cihaz düğümünü al" dedim. İdeal olarak, büyük / küçük numaraları eşleşen, her satırda bir düğüm olan tüm cihaz düğümleriyle bir liste almak istiyorum. Bunun için hazır bir aracımız olmadığı garip. Cevap btw için teşekkürler!
Dmitry Frank

Yanıtlar:


7

Ben sys pseudofilesystem kullanarak daha basit bir yaklaşım buldum, / sys / dev de daha sonra major / minor tarafından sipariş cihazlara sahip, dosya uevent cihaz adı ve diğer bilgileri bir grup içerir.

Yani mesela,

  for file in $(find /sys/dev/ -name 7:0); do  
      source ${file}/uevent; echo $DEVNAME;
  done;

Echoes,

loop0
vcs

Not: Bu Debian Wheezy'de test edilmiştir


adından geriye doğru bulmak için:for file in $(ls /sys/dev/block/ ); do source /sys/dev/block/${file}/uevent; if [ "$DEVNAME" == "sda1" ] ; then echo ${file}; fi done;
BBK

5

Ne demek istediğinden emin değilim.

mknod foo b 8 0

fooBüyük 8 ve küçük 0 ile blok aygıtı olarak adlandırılan aygıt dosyasını oluşturur. /devAynı türde, büyük ve küçük olan dosyalardan birini veya herhangi birini bulmak istiyorsanız, (ile zsh) yapabilirsiniz:

  • Blok cihaz için 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 cihazı için 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
    

Herhangi bir şeyin dosya oluşturabileceğini unutmayın /dev. Çok eski günlerde orada statik dosyalar oluşturan bir betikti. Bir noktada, özel bir dosya sisteminiz bile vardı /proc.

Linux'un modern sürümlerinde, genellikle udevçekirdekten gelen girdilere dayanır.

Temel aygıt dosyası için seçtiği ad DEVNAME, çekirdek tarafından sağlanan temele dayanır . udevkurallar değişebilir, ancak genellikle değişmez ve bazı udevkurallar kolaylık sağlamak için biraz daha sembolik bağlantılar ekleyecektir ( /dev/disk/by...bunlar gibi ).

Şuna DEVNAMEbakarak majör: minörden çekirdeğe gidebilirsiniz :

$ 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

Bu bilgileri udevmikeserv'in gösterdiği gibi veritabanından da alabilirsiniz .


5

Görünüşe göre daha basit bir şekilde yapılabilir udevadmve nasıl olduğunu öğrendim.

Almak için DEVNAMEgelen udevadmsizin sadece yapmanız gereken:

udevadm info -rq name $PATH

Örneğin, /devadının /sys/dev/char/5:1ne olacağını bilmek isterseniz:

udevadm info -rq name /sys/dev/char/5:1

ÇIKTI

/dev/console

-rSeçenek belirtmektir --rootsadece okurdum yukarıda onsuz sonucu - ed yolunu console. -qSeçenek bir veritabanı belirtir --queryve işlenen alır nameburada - biz istediğimiz için DEVNAME.

Yalnızca büyük verilen bir karakter ve / veya blok cihazının yolunu bulmanın çok basit bir yolu: küçük sayılar şöyle görünebilir:

mmdev() for d in /sys/dev/[cb]*/$1:$2
        do  [ -e "$d" ] || return
            printf %c:%s: "${d#/*/*/}" "${d##*/}"
            udevadm info -rq name "$d"
        done

Yani koşuyor:

mmdev 8 0

baskılar ...

b:8:0:/dev/sda

İşte ilk yazdığım.

majminpath() {
    set -- ${1##*[!0-9]*} ${2##*[!0-9]*}
    udevadm info --export-db |
    sed 's|^[^=]*DEVNAME=||
         \|^[^/]|!h;/MAJOR=/N
         \|='"$1\n.*=${2?}"'$|!d;g'
}

Bu sadece udevadm info --export-dbeşleşen numaraların çıktısını tarar . Çıktı şöyle görünür:

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

İş akışı şöyledir:

  • [^=]*DEVNAME=dizeyi her satırın başından ayırmaya çalışın

  • bir satırın ilk karakteri yoksa veya ilk karakteri /o satırı heski alana kopyalarsa

  • bir çizgi eşleşirse desen alanına MAJOR=ek Ngiriş satırı ekler

  • desen alanında eşleşen 2 satır varsa eski alanı desen alanı üzerine =$1\n.*=$2$kopyalayın hve otomatik yazdırın; başka desen alanını sil

Yani ben yaparsam:

majminpath 7 133 ; majminpath 8 0 ; majminpath 8 1

ÇIKTI

/dev/vcsa5
/dev/sda
/dev/sda1

Ancak, @xae'nin işaret ettiği gibi, blok / karakter tipi cihazlar maj: min kombinasyonlarını paylaşabilir ve bu nedenle arama başına birden fazla yol yazdırılabilir.


1
Ne yazık ki o kadar kolay değil, bir blok ve bir karakter cihazı aynı büyük sayıyı paylaşabilir. / Proc / device dosyasına bir göz atın.
xae

Altsistemi kontrol etmeliyim - bu doğru. Teşekkürler, @xae.
mikeserv

1

Ne yazık ki , /sys/devhiyerarşi çekirdeğe sadece 2.6.27 kadar geçmiştir ( bkz . Çekirdek kod tabanına karşı ilgili taahhüt ), bu yüzden “çatallı” bir yaklaşıma ihtiyacımız var.

Izin vermek $Mve $m, sırasıyla, büyük ve küçük sayı bizim aygıt dosyası.

Post 2.6.27 çekirdekler

Diğerleri tarafından önerildiği gibi, en basit yaklaşım sysfs“sanal” dosya sisteminin gücünü doğrudan $M:$mklasör altında adlandırılan dosyaları kovalayarak ortaya çıkarır /sys/dev(cihazımızın bir karakter olup olmadığını bilmiyorsak birden fazla dosya beklenmelidir. veya blok tabanlı bir ueventdosya ) ve daha sonra dosyayı (ad alanı kirliliğini önlemek için bir alt kabukta) kaynaklayın:

for file in $(find /sys/dev/ -name $M:$m)
do
    (
        source ${file}/uevent
        echo $DEVNAME
    )
done

2.6.27 öncesi çekirdek

Basitlik adına, dosyamızın bir blok cihaz olduğunu varsayalım (benzer bir yaklaşım karakter cihazları için de geçerlidir). Dizini, adı olan her dosyanın içeriğini (bu klasörün altında) inceleyerek hiyerarşi $M:$mboyunca arayacağız . Eğer böyle bir dosya, o zaman bizim cihazın adı olacağı kesindir:/sys/blockdev/sys/block/<...>/<DEV>/devDEV

dirname "$(find "/sys/block" -name dev | xargs -r grep -l ^$M:$m$)"

0

Linux'ta /procsanal dosya sistemindeki belirli dosyalardan yararlanmak mümkündür .

$ 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

Desenin basit şekli, çıktıda istenen cihaz hakkında zaten bilgi sağlar, ancak sadece belirli bir dizeyi çıkarmak için ek filtreleme de mümkündür.


0

Bir kütüphane işlevi vardır: makedev()

#include <sys/sysmacros.h>
dev_t makedev(unsigned int maj, unsigned int min);

Büyük ve küçük cihaz kimlikleri verildiğinde, makedev () bunları işlev sonucu olarak döndürülen bir cihaz kimliği üretmek için birleştirir.

Daha fazla ayrıntı için şu adresi ziyaret edin: http://man7.org/linux/man-pages/man3/major.3.html

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.