जब आउटपुट फ़ाइल / dev / null होती है, तो टार फ़ाइल सामग्री को छोड़ता क्यों दिखाई देता है?


21

मेरे पास एक निर्देशिका है जिसमें 400 से अधिक GiB डेटा है। मैं जांचना चाहता था कि सभी फाइलें त्रुटियों के बिना पढ़ी जा सकती हैं, इसलिए मैंने सोचा था कि tarयह एक सरल तरीका है /dev/null। लेकिन इसके बजाय मैं निम्नलिखित व्यवहार देखता हूं:

$ time tar cf /dev/null .

real    0m4.387s
user    0m3.462s
sys     0m0.185s
$ time tar cf - . > /dev/null

real    0m3.130s
user    0m3.091s
sys     0m0.035s
$ time tar cf - . | cat > /dev/null
^C

real    10m32.985s
user    0m1.942s
sys     0m33.764s

ऊपर की तीसरी कमान पहले से ही काफी लंबे समय तक चलने के बाद Ctrl+ द्वारा जबरन बंद कर दी गई थी C। इसके अलावा, जब पहले दो कमांड काम कर रहे थे, स्टोरेज डिवाइस की गतिविधि सूचक .लगभग हमेशा बेकार थी। तीसरे आदेश के साथ सूचक लगातार जलाया जाता है, जिसका अर्थ है अत्यधिक व्यस्तता।

तो ऐसा लगता है कि, जब tarयह पता लगाने में सक्षम है कि इसकी आउटपुट फाइल है /dev/null, यानी जब /dev/nullफ़ाइल हैंडल को खोलने के लिए सीधे खोला जाता है जो tarलिखता है, तो फ़ाइल बॉडी स्किप हो जाती है। ( vकरने के लिए विकल्प जोड़ना tarनिर्देशिका में सभी फ़ाइलों को tar'लाल' प्रिंट करता है ।)

तो मुझे आश्चर्य है, ऐसा क्यों है? क्या यह किसी प्रकार का अनुकूलन है? यदि हाँ, तो tarऐसे विशेष मामले के लिए ऐसा संदिग्ध अनुकूलन क्यों करना चाहते हैं?

मैं लिनक्स 4.14.105 amd64 पर glibc 2.27 के साथ GNU टार 1.26 का उपयोग कर रहा हूं।


7
एक व्यावहारिक विकल्प के रूप में, कुछ इस तरह से विचार करें find . -type f -exec shasum -a256 -b '{}' +। न केवल यह वास्तव में सभी डेटा को पढ़ता है और चेक करता है , लेकिन यदि आप आउटपुट को स्टोर करते हैं, तो आप बाद में यह जांचने के लिए इसे चला सकते हैं कि फ़ाइलों की सामग्री नहीं बदली है।
इल्मरी करोनन

बातें मापने के लिए आप भी उपयोग कर सकते हैं pv: tar -cf - | pv >/dev/null। यह समस्या को दरकिनार करता है और आपको एक प्रगति की जानकारी (विभिन्न pvविकल्प) देता है
xenoid

आपने GNU टार के एक प्रसिद्ध मिस फीचर को हिट किया। gtar -cf /dev/zero ...आपको जो पसंद है उसे पाने के लिए उपयोग करें ।
शास्त्री

जवाबों:


25

यह है एक प्रलेखित अनुकूलन :

जब आर्काइव बनाया जा रहा है /dev/null, GNU टार इनपुट और आउटपुट ऑपरेशन को कम करने की कोशिश करता है। अमांडा बैकअप सिस्टम, जब जीएनयू टार के साथ उपयोग किया जाता है, में एक प्रारंभिक आकार पास होता है जो इस सुविधा का उपयोग करता है।


4
आह, यह मेरे द्वारा स्थापित मैन पेज में वर्णित नहीं था। info tarइसके बजाय कोशिश करनी चाहिए थी ...
रुस्लान

9
वे वास्तव में आदमी और जानकारी पृष्ठों को सिंक में रखना चाहिए, यह व्यावहारिक रूप से एक बग है कि वे नहीं हैं
Xen2050

9
@Ruslan अधिकांश GNU उपयोगिताओं के साथ, मैन पेज में केवल एक संक्षिप्त सारांश होता है, मूल रूप से केवल इतना अच्छा होता है कि आपको याद रहे कि इसमें कुछ करने का विकल्प है लेकिन विकल्प का नाम याद नहीं है। पूर्ण प्रलेखन एक ऐसे प्रारूप में है, जो मैन पेजों पर अच्छी तरह से अनुवाद नहीं करता है और infoब्राउज़र में HTML के साथ या उसके रूप में उपलब्ध है।
गिल्स का SO- बुराई का होना बंद करो '


8

यह विभिन्न प्रकार के कार्यक्रमों के साथ हो सकता है, उदाहरण के लिए, मेरे पास एक बार उपयोग करते समय वह व्यवहार था cp file /dev/null; मेरी डिस्क पढ़ने की गति का अनुमान लगाने के बजाय, आदेश कुछ मिलीसेकंड के बाद वापस आ गया।

जहां तक ​​मुझे याद है, वह सोलारिस या एआईएक्स पर था, लेकिन सिद्धांत सभी प्रकार के यूनिक्स-वाई सिस्टम पर लागू होता है।

पुराने समय में, जब कोई प्रोग्राम किसी फाइल को कहीं पर कॉपी करता है, तो वह readकॉल के बीच वैकल्पिक रूप से डिस्क से कुछ डेटा प्राप्त करता है (या फ़ाइल डिस्क्रिप्टर जो भी हो) को मेमोरी में भेज देता है (गारंटी के साथ सब कुछ वहीं होता है जब readरिटर्न और writeकॉल ) (जो स्मृति का हिस्सा लेते हैं और सामग्री को गंतव्य पर भेजते हैं)।

हालाँकि, इसे प्राप्त करने के लिए कम से कम दो नए तरीके हैं:

  • लिनक्स में सिस्टम कॉल हैं copy_file_range(अन्य सभी पर यूनिक्स के लिए पोर्टेबल नहीं) और sendfile(कुछ हद तक पोर्टेबल; मूल रूप से नेटवर्क में एक फ़ाइल भेजने का इरादा है, लेकिन अब किसी भी गंतव्य का उपयोग कर सकते हैं)। वे स्थानान्तरण का अनुकूलन करने का इरादा रखते हैं; यदि प्रोग्राम उन में से एक का उपयोग करता है, तो यह आसानी से बोधगम्य है कि कर्नेल लक्ष्य को पहचानता है /dev/nullऔर सिस्टम कॉल को नो-ऑप में बदल देता है

  • प्रोग्राम mmapफ़ाइल सामग्री प्राप्त करने के लिए उपयोग कर सकते हैं read, इसका मूल अर्थ यह है कि "सुनिश्चित करें कि डेटा वहाँ है जब मैं उस मेमोरी को एक्सेस करने का प्रयास करता हूं" के बजाय "सुनिश्चित करें कि सिस्टम कॉल रिटर्न होने पर डेटा वहाँ है"। तो एक प्रोग्राम mmapस्रोत फ़ाइल कर सकता है, फिर writeमैप किए गए मेमोरी के उस हिस्से पर कॉल करें । हालाँकि, जैसा कि लेखन /dev/nullको लिखित डेटा तक पहुंचने की आवश्यकता नहीं है, "सुनिश्चित करें कि यह वहां है" स्थिति कभी भी ट्रिगर नहीं हुई है, जिसके परिणामस्वरूप फ़ाइल को या तो पढ़ा नहीं जा रहा है।

जो, इन दो तंत्र की जब यह पता लगाता है इसे करने के लिए लिख रही gnu टार किसी भी उपयोग करता है, और सुनिश्चित नहीं हैं /dev/null, लेकिन वे कारण है कि किसी भी कार्यक्रम, कर रहे हैं जब पढ़ने के लिए गति की जाँच करने के लिए प्रयोग किया जाता , के साथ चलाने की जानी चाहिए | cat > /dev/nullबजाय > /dev/null- और क्यों | cat > /dev/nullकरना चाहिए जा बचा अन्य सभी मामलों में।


मुझे लगता है कि जीएनयू tarसूचना पृष्ठ (अन्य उत्तर देखें) में निहितार्थ यह है कि इसके लिए एक विशेष मोड है, जो संभवतः उन्हें खोलने के बिना फ़ाइलों को केवल आँकड़े देता है। वास्तव में मैं सिर्फ tar cf /dev/null foo*एक जोड़ी फ़ाइलों और हाँ के साथ जाँच की , सिर्फ newfstatat(..., AT_SYMLINK_NOFOLLOW)सिस्टम कॉल, यह भी नहीं है open()कि अद्यतन हो सकता है। लेकिन तंत्र का वर्णन करने के लिए +1 जहां यह विशेष रूप से इसका पता लगाए बिना हो सकता है।
पीटर कॉर्डेस

चाहिए mmap विवरण "पढ़ने पढ़ने डेटा" "पहुँच के बजाय लिखित डेटा?"
वेन कॉनराड

splice(2)लिनक्स पर भी देखें । वास्तव में, लिनक्स के cat > /dev/nullसाथ pv -q > /dev/null(जिसके उपयोग splice()से) की जगह, ओवरहेड को कम करेगा। या dd bs=65536 skip=9999999999 2> /dev/null, या wc -c > /dev/nullया tail -c1 > /dev/null...
स्टीफन Chazelas
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.