प्रमुख / मामूली संख्या जोड़ी द्वारा डिवाइस नोड प्राप्त करें


12

के तहत प्रत्येक डिवाइस नोड /devकी अपनी प्रमुख / छोटी संख्या जोड़ी है। मुझे पता है कि हम इस तरह से डिवाइस नोड से संख्याओं के इस जोड़े को पुनः प्राप्त कर सकते हैं stat, जैसे:

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

या, ls -lइन नंबरों को भी दिखाता है।

लेकिन हम दिए गए प्रमुख और मामूली संख्याओं के द्वारा डिवाइस नोड (ओं) को कैसे प्राप्त कर सकते हैं? जिस तरह से मैं जानता हूँ कि कुछ प्रकार ls -l+ awkचाल है, लेकिन मुझे वास्तव में उम्मीद है कि बेहतर समाधान है।


@mikeserv, हां मुझे पता है कि कुछ डिवाइस इन नंबरों को साझा कर सकते हैं, इसलिए मैंने अपने प्रारंभिक प्रश्न में उल्लेख किया है: "डिवाइस नोड (ओं) को प्राप्त करें"। आदर्श रूप से मैं सभी डिवाइस नोड्स के साथ एक सूची प्राप्त करना चाहता हूं जिनके प्रमुख / मामूली संख्याएं मेल खाती हैं, प्रति पंक्ति एक नोड। यह अजीब है कि हमारे पास इसके लिए कोई तैयार उपकरण नहीं है। उत्तर btw के लिए धन्यवाद!
दिमित्री फ्रैंक

जवाबों:


7

मुझे sys pseudofilesystem का उपयोग करते हुए एक सरल दृष्टिकोण मिला , / sys / dev पर आपके पास प्रमुख / नाबालिग द्वारा टाइप किए गए उपकरण हैं , फ़ाइल uevent में डिवाइस का नाम और अन्य जानकारी का एक गुच्छा है।

उदाहरण के लिए,

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

गूँज,

loop0
vcs

नोट: यह डेबियन व्हीज़ी में परीक्षण किया गया था


देव नाम से पीछे की ओर खोजने के लिए:for file in $(ls /sys/dev/block/ ); do source /sys/dev/block/${file}/uevent; if [ "$DEVNAME" == "sda1" ] ; then echo ${file}; fi done;
BBK

5

पक्का नहीं आपका क्या मतलब है।

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

लिनक्स के आधुनिक संस्करणों पर, यह आमतौर 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 ने दिखाया है।


5

जाहिरा तौर पर यह अधिक बस के साथ किया जा सकता है 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

एक चार और / या ब्लॉक डिवाइस के लिए रास्ता खोजने का एक बहुत ही सरल साधन केवल दिए गए प्रमुख: मामूली संख्या की तरह लग सकता है:

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 बताते हैं, ब्लॉक / चार प्रकार के डिवाइस, मेजर: मिन कॉम्बिनेशन साझा कर सकते हैं, और इसलिए यह संभवतः प्रति कॉल एक से अधिक पथ प्रिंट कर सकता है।


1
दुर्भाग्य से यह इतना आसान नहीं है, एक ब्लॉक और एक चरित्र डिवाइस एक ही प्रमुख संख्या साझा कर सकते हैं। फ़ाइल / proc / उपकरणों पर एक नज़र डालें।
xae

मुझे सबसिस्टम चेक करना होगा - यह सही है। धन्यवाद, @xae
mikeserv

1

काश , /sys/devपदानुक्रम केवल कर्नेल में 2.6.27 के रूप में देर से जोड़ा गया था ( cf. कर्नेल कोडबेस के खिलाफ प्रासंगिक प्रतिबद्ध ), इसलिए हमें "द्विभाजित" दृष्टिकोण की आवश्यकता है।

चलो $Mऔर $mक्रमश: हमारे डिवाइस फ़ाइल की बड़ी और छोटी संख्या हो।

पोस्ट 2.6.27 गुठली

जैसा कि दूसरों ने सुझाव दिया है, सरल दृष्टिकोण sysfs"वर्चुअल" फ़ाइल सिस्टम की शक्ति को उजागर करता है, $M:$mफ़ोल्डर के तहत नामित फ़ाइलों के लिए सीधे पीछा करते हुए /sys/dev(एक से अधिक फ़ाइल की उम्मीद की जानी है, अगर हम नहीं जानते कि क्या हमारा डिवाइस एक चरित्र है- या एक ब्लॉक आधारित एक), और फिर सोर्सिंग ueventफ़ाइल (एक subshell में इतना नाम स्थान प्रदूषण को रोकने के लिए के रूप में):

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

पूर्व 2.6.27 गुठली

हमें लगता है, सादगी के लिए, कि हमारी फ़ाइल एक ब्लॉक डिवाइस है (चरित्र उपकरणों के लिए एक समान दृष्टिकोण लागू होता है)। हम $M:$mपूरे /sys/blockपदानुक्रम में स्ट्रिंग की खोज करेंगे , (उस फ़ोल्डर के नीचे) की जांच करके, हर फ़ाइल की सामग्री जिसका नाम होता है dev। यदि /sys/block/<...>/<DEV>/devऐसी एक फ़ाइल है, तो DEVहमारे डिवाइस का नाम होना तय है:

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

0

लिनक्स पर /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

पैटर्न का सरल रूप पहले से ही आउटपुट में वांछित डिवाइस के बारे में जानकारी प्रदान करता है, हालांकि केवल एक विशेष स्ट्रिंग निकालने के लिए अतिरिक्त फ़िल्टरिंग संभव है।


0

एक पुस्तकालय समारोह है: makedev()

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

प्रमुख और मामूली डिवाइस आईडी को देखते हुए, makedev () फ़ंक्शन आईडी के रूप में लौटाए गए डिवाइस आईडी का उत्पादन करने के लिए इन्हें जोड़ती है।

अधिक जानकारी के लिए देखें: http://man7.org/linux/man-pages/man3/major.3.html

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.