जांचें कि क्या 2 निर्देशिकाओं को लिनक्स पर एक ही विभाजन पर होस्ट किया गया है


9

मैं कैसे जांच कर सकता हूं /my/dirकि क्या समान विभाजन पर है /?

यह एक स्क्रिप्ट के भीतर एकीकरण के लिए है। बाइंड माउंट्स को सही तरीके से हैंडल किया जाना चाहिए। POSIX संगत समाधान का स्वागत करते हैं।


"बाइंड माउंट को सही ढंग से संभाला जाना चाहिए।" लेकिन आप क्या सही मानते हैं? आपके प्रश्न की व्याख्या किसी भी तरह से की जा सकती है।
गिलेस का SO-

@ गिल्स ने मूल शीर्षक में "माउंटेड" के बजाय "होस्टेड" लिखा, किसी ने भ्रम IMHO जोड़कर संपादित किया। फिर भी मेरा प्रश्न शरीर स्पष्ट है: "एक ही विभाजन पर", वह एक ही भौतिक विभाजन पर है, जो भी दो फाइलों / निर्देशिकाओं तक पहुंचने के लिए पथ या माउंटपॉइंट का उपयोग किया जाता है।
टोटर

जवाबों:


6

आप इसे स्टेट के साथ देख सकते हैं:

$ stat -c '%d %m' /proc/sys/
3 /proc

आपको डिवाइस नंबर दिखाता है और जहां आपकी निर्देशिका माउंट की गई थी।


1
अच्छा लगा, लेकिन statशेल कमांड पोसिक्स नहीं है ...
टोटर

नहीं? आपको कैसे मालूम?

इस सूची में नहीं ।
Totor

मेरी गलती है। लेकिन अगली बार इस लिंक को पहले ही दिखा दें।

5

निम्न आदेश फ़ाइल वाले आरोह बिंदु के लिए एक विशिष्ट नाम देता है $file:

df -P -- "$file" | awk 'NR==2 {print $1}'

यह किसी भी POSIX सिस्टम पर काम करता है। -Pविकल्प के लिए एक उम्मीद के मुताबिक प्रारूप लगाता है; दूसरी पंक्ति का पहला क्षेत्र "फ़ाइल सिस्टम नाम" है। इस प्रकार, दो फ़ाइलों की जाँच करने के लिए एक ही आरोह बिंदु के नीचे हैं:

if [ "$(df -P -- "$file1" | awk 'NR==2 {print $1}')" = \
     "$(df -P -- "$file2" | awk 'NR==2 {print $1}')" ]; then
  echo "$file1 and $file2 are on the same filesystem" ; fi

या, प्रक्रिया चालान के एक जोड़े को बचाने के लिए:

if df -P -- "$file1" "$file2" |
   awk 'NR!=1 {dev[NR] = $1} END {exit(dev[2] != dev[3])}'; then
  echo "$file1 and $file2 are on the same filesystem" ; fi

कुछ ऑपरेटिंग सिस्टम के वॉल्यूम नामों में स्थान हो सकते हैं। dfइस मामले में आउटपुट पार्स करने का कोई पूरी तरह से विश्वसनीय तरीका नहीं है ।

हुड के तहत, आप फाइल सिस्टम की पहचान कर सकते हैं जिसमें st_devरिटर्न द्वारा फाइल की गई फाइल है stat। शेल स्क्रिप्ट से ऐसा करने का कोई पोर्टेबल तरीका नहीं है। कुछ प्रणालियों की एक statउपयोगिता है, लेकिन इसका सिंटैक्स भिन्न होता है:

  • गैर-एम्बेडेड लिनक्स पर, जीएनयू कोर्यूटिल्स के साथ सिग्विन या अन्य सिस्टम, जब बुलाया जाता है , statतो st_devफ़ील्ड की रिपोर्ट करता है stat -c %D -- "$file"
  • कुछ बिजीबॉक्स इंस्टालेशन में शामिल है statजो GNU कोरुटिल्स के साथ संगत है। दूसरों के पास विकल्प के statबिना है %c; आप उपयोग कर सकते हैं stat -t -- "$file" | awk '{print $8}'लेकिन यह केवल तभी काम करता है जब फ़ाइल नाम में व्हॉट्सएप नहीं होता है, या stat -t -- "$file" | awk 'END {print $(NF-8)}'जो मनमाने ढंग से फ़ाइल नामों के साथ आता है, लेकिन statआउटपुट में फ़ील्ड के भविष्य के परिवर्धन के साथ नहीं ।
  • बीएसडी सिस्टम की एक अलग statउपयोगिता है जिसकी आवश्यकता होती है stat -f %d -- "$file"
  • सोलारिस, AIX और अन्य की कोई statउपयोगिता नहीं है।

यदि पर्ल उपलब्ध है, तो आप उपयोग कर सकते हैं

perl -e 'print ((stat($ARGV[0]))[0])' -- "$file"

और तुलना करने के लिए:

perl -e 'exit((stat($ARGV[0]))[0] != (stat($ARGV[1]))[0])' -- "$file1" "$file2"

ध्यान दें कि कुछ कोने मामले हैं जहां वांछित परिणाम स्पष्ट नहीं है। उदाहरण के लिए, लिनक्स के बाइंड माउंट के साथ, के बाद mount --bind /foo /bar, /fooऔर /barएक ही फाइल सिस्टम माना जाता है। यह हमेशा संभव है कि दो फाइलें वास्तव में एक ही डिवाइस पर स्थित हों, लेकिन आप कभी नहीं जान पाएंगे: उदाहरण के लिए, यदि फाइलें दो अलग-अलग नेटवर्क माउंट पर हैं, तो क्लाइंट के पास यह जानने का कोई तरीका नहीं है कि सर्वर अलग-अलग फाइल सिस्टम का निर्यात कर रहा है या नहीं।

यदि फ़ाइलें निर्देशिकाएं हैं और आप उन्हें लिख सकते हैं, तो एक अन्य विधि एक अस्थायी फ़ाइल बनाने और हार्ड लिंक बनाने का प्रयास है। यह एक लिनक्स बाइंड माउंट्स पर एक नकारात्मक परिणाम की सूचना देता है।

tmp1=$(TMPDIR=$dir1 mktemp)
tmp2=$(TMPDIR=$dir2 mktemp)
if ln -f -- "$tmp1" "$tmp2"; then
  echo "$dir1 and $dir2 are on the same filesystem, which supports hard links"
fi
rm -f "$tmp1" "$tmp2"

समस्या: dfहमेशा की तरह यह करने के लिए एक सिमलिंक डिवाइस का नाम देना नहीं है, लेकिन कुछ समय /dev/disk/by-uuid/ca09b761-ae1b-450f-8a46-583327b48fb4बनाने dfविश्वसनीय नहीं। एकमात्र विश्वसनीय विकल्प अब तक एक- statआधारित समाधान का उपयोग कर रहा है ।
टॉरेंट

@ कोई बात नहीं है: dfडिवाइस के लिए जो भी नाम रिपोर्ट करता है, वह दो इनवोकेशन के बीच सुसंगत है, इसलिए यह तुलना के लिए ठीक है।
गिल्स एसओ- बुराई को रोकना '

नहीं, यह काम नहीं करता है, मैंने इसका परीक्षण किया। डेबियन व्हीज़ी के यहाँ, एक ही dfरिपोर्ट /dev/sda6और /dev/disk/by-uuid/ca09b..., दोनों एक ही डिवाइस का उल्लेख करते हैं, लेकिन अलग-अलग माउंट पॉइंट। प्रत्येक माउंट बिंदु से फ़ाइलों के साथ प्रयास करते समय स्ट्रिंग तुलना परीक्षण स्पष्ट रूप से विफल हो जाता है।
टॉटर

@ टॉटर आम तौर पर आप एक ही ब्लॉक डिवाइस को दो बार माउंट नहीं कर सकते। जैसा कि मैंने अपने उत्तर में संकेत दिया है, ऐसे कोने मामले हैं जैसे कि बाँध आरोह जो अलग-अलग हो सकते हैं या रिपोर्ट नहीं किए जा सकते हैं।
गिलेस एसओ- बुराई का होना बंद करो '

फिर भी यह डेबियन स्क्वीज़ और व्हीज़ी पर पूरी तरह से काम करता है: mount /dev/sda6 /mnt1इसके बाद mount /dev/sda6 /mnt2आकर्षण की तरह काम करता है। cat /proc/mountsइसके साथ ठीक है हालाँकि, यह केवल Wheezy के बाद से /dev/disk/by-uuid/ca09b...है dfजो रूट फाइल सिस्टम के लिए डिवाइस के रूप में दिखाया गया है । इस सिमलिंक या UUID=ca09b...माउंट सिंटैक्स का उपयोग करके इसे माउंट करने के और प्रयास करने से इसके अलावा और कुछ भी दिखाई नहीं /dev/sda6देता है df(मुझे नहीं पता कि बूट प्रक्रिया के दौरान इसे कैसे किया जाए, लेकिन यह चिंता का विषय नहीं है)।
टोटर

4
test $(df -P $path1 $path2 | awk '{if (NR!=1) {print $6}}' | uniq | wc -l) -eq 1

किसी भी पथ के साथ काम करता है।


के उत्पादन में पार्स dfहै हमेशा एक अच्छा विचार नहीं
जोसेफ आर।

1
@ मैं माउंटपॉइंट ( $6) की जाँच कर रहा हूँ , डिवाइस का नाम नहीं ( $1), ताकि कोई समस्या न हो।
n।

1
@ जोसेफआर यह POSIX में सबसे अच्छा है। n.st: पहले फ़ील्ड की जांच क्यों नहीं की गई? इससे कोई फर्क नहीं पड़ता कि डिवाइस का उपयोग करने के लिए किस पथ का उपयोग किया गया था, अगर यह एक ही माउंट बिंदु है तो आउटपुट सुसंगत होगा।
गिल्स एसओ- बुराई को रोकना '

यह बाइंड माउंट्स के साथ काम नहीं करता है।
टोटर

0

POSIX में उपलब्ध सबसे अच्छा फुलप्रूफ सॉल्यूशन स्टेट्स (2) फंक्शन द्वारा उपलब्ध कराई गई फाइलों की डिवाइस आईडी की तुलना है ।

पर्ल के पास एक समान स्टेटमेंट फंक्शन है जैसा कि गिल्स ने बताया :

perl -e 'exit((stat($ARGV[0]))[0] != (stat($ARGV[1]))[0])' -- file1 file2

लेकिन "POSIX तरीका" एक C प्रोग्राम का उपयोग करने के लिए है:

./checksamedev file1 file2

कौन सा स्रोत कोड इस प्रकार है:

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

int main(int argc, char* argv[]) {
    struct stat s1, s2;
    if( argc==3 && lstat(argv[1], &s1)==0 && lstat(argv[2], &s2)==0 )
        return !(s1.st_dev == s2.st_dev);
    return 2;
}

यदि दोनों फ़ाइलों की डिवाइस आईडी समान हैं, तो उन्हें एक ही फाइल सिस्टम पर होस्ट किया जाता है, जिस स्थिति में, ऊपर दिए गए कमांड 0 (किसी अन्य प्रकार से)। के साथ जाँच करें echo $?

यह बाइंड माउंट्स के साथ अच्छी तरह से काम करता है, लेकिन संभवतः नेटवर्क माउंट्स के साथ नहीं होगा।

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