वास्तविक निर्देशिका आकार (डु से बाहर) कैसे प्राप्त करें?


17

UNIX / Linux मानक टूल का उपयोग करके मुझे वास्तविक निर्देशिका आकार कैसे मिलेगा?

वैकल्पिक प्रश्न: मैं कैसे मिलता है डु मुझे वास्तविक निर्देशिका आकार (नहीं डिस्क उपयोग) को दिखाने के लिए?

चूंकि लोगों को "आकार" शब्द की अलग-अलग परिभाषाएं लगती हैं: मेरी "निर्देशिका आकार" की परिभाषा उस निर्देशिका के भीतर सभी नियमित फाइलों का योग है।

मैं निर्देशिका इनोड के आकार या जो भी (ब्लॉक * ब्लॉक आकार) फाइलों के बारे में परवाह नहीं करता हूं, वे संबंधित फाइल सिस्टम पर ले जाते हैं। 3 फ़ाइलों के साथ एक निर्देशिका, 1 बाइट प्रत्येक, 3 बाइट्स की एक निर्देशिका आकार (मेरी परिभाषा के द्वारा) है।

डु का उपयोग करके निर्देशिका आकार की गणना अविश्वसनीय लगती है।
उदाहरण के लिए, mkdir foo && du -b fooरिपोर्ट "4096 फू", 0 बाइट्स के बजाय 4096 बाइट्स। बहुत बड़ी निर्देशिकाओं के साथ, द्वारा बताई गई निर्देशिका आकार du -hs100 GB (!) और अधिक (संपीड़ित फ़ाइल सिस्टम) द्वारा बंद किया जा सकता है।

तो क्या (उपकरण / विकल्प) वास्तविक निर्देशिका आकार प्राप्त करने के लिए इस्तेमाल किया जाना है?


नए स्थान पर किस फाइलसिस्टम का उपयोग किया जाता है - क्या यह xfsकिसी भी संयोग से है?
सर्गेई व्लासोव


और अगर आपका नया FS वास्तव में XFS है, तो बहुत बढ़ा हुआ डिस्क उपयोग संभवतः आक्रामक प्रचार के कारण होता है , जो डिस्क उपयोग की लागत पर फ़ाइल विखंडन को कम करता है।
सेर्गेई व्लासोव

जवाबों:


8

यहाँ एक स्क्रिप्ट है जो मानव रीडेबल डायरेक्टरी साइज़ को प्रदर्शित करती है जो यूनिक्स मानक टूल्स (POSIX) का उपयोग करती है।

#!/bin/sh
find ${1:-.} -type f -exec ls -lnq {} \+ | awk '
BEGIN {sum=0} # initialization for clarity and safety
function pp() {
  u="+Ki+Mi+Gi+Ti+Pi+Ei";
  split(u,unit,"+");
  v=sum;
  for(i=1;i<7;i++) {
    if(v<1024) break;
    v/=1024;
  }
  printf("%.3f %sB\n", v, unit[i]);
}
{sum+=$5}
END{pp()}'

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

$ ds ~        
72.891 GiB

और अब मुझे एक और विकल्प मिला, जो सभी सुझाए गए lsइनवोकेशन में गायब है -q:। इस विकल्प के बिना स्क्रिप्ट टूट जाएगी यदि कुछ फ़ाइल नाम में newline वर्ण हैं। वास्तव में विश्वसनीय शेल स्क्रिप्ट लिखना बहुत कठिन है ...
सर्गेई व्लासोव

@SergeyVlasov मैंने जो स्क्रिप्ट पोस्ट की है, उसे ऐसी फ़ाइलों के साथ नहीं तोड़ना चाहिए, केवल अतिरिक्त लाइनों की अनदेखी करना। एकमात्र समस्या का मामला होगा सावधानी से तैयार की गई फ़ाइल में एक अतिरिक्त लाइन विटठा पांचवीं बृहदान्त्र होती है जिसमें एक संख्यात्मक मान होता है। आपका सुझाव वास्तव में उस स्थिति से बचना होगा। टिप के लिए धन्यवाद, स्क्रिप्ट अपडेट की गई।
जूलियरे

विलक्षण उत्तर। +1 टू
यू

यह सबसे विश्वसनीय समाधानों में से एक है। यह उन फ़ाइल नामों के साथ काम करता है जिनमें रिक्त स्थान या उद्धरण हैं और यह मानव-पठनीय आकार को प्रिंट करता है।
बेसिक 6

@KIAaze मेरे कोड की समीक्षा करने और उसे ठीक करने के लिए धन्यवाद!
जुलियाग्रे

8

कुछ संस्करण डिस्क उपयोग के बजाय स्पष्ट आकार दिखाने duके तर्क का समर्थन करते हैं --apparent-size। तो आपकी आज्ञा होगी:

du -hs --apparent-size

Ubuntu 12.04 LTS के साथ शामिल होने के लिए मैन पेज से:

--apparent-size
      print apparent sizes,  rather  than  disk  usage;  although  the
      apparent  size is usually smaller, it may be larger due to holes
      in (`sparse') files, internal  fragmentation,  indirect  blocks,
      and the like

1
काम नहीं करता है: खाली
डायरियों के

1
यह मेरे लिए काम किया।
कंबोडोड

2
जब आप विभिन्न फ़ाइल सिस्टम पर निर्देशिकाओं की तुलना कर रहे हैं, तो यह काफी अलग आकार देता है। उदाहरण के लिए एक ही फ़ोल्डर में zf फ़ाइल सिस्टम पर 290Gb का स्पष्ट आकार और exFat का 324Gb है। ऊपर दिए गए समाधान समान आकार देते हैं।
21

5

यह मानते हुए कि आपके पास duGNU कोरुटिल्स हैं, इस कमांड को फ़ाइलों की संख्या पर किसी भी मनमानी सीमा के बिना निर्देशिका के अंदर नियमित फ़ाइलों की मनमानी संख्या के कुल स्पष्ट आकार की गणना करनी चाहिए:

find . -type f -print0 | du -scb --files0-from=- | tail -n 1

यदि कुछ हार्डलिंक फ़ाइलें अंदर हैं, तो -lविकल्प जोड़ें duऔर आप प्रत्येक हार्डलिंक को अलग से गिनना चाहते हैं (डिफ़ॉल्ट रूप से duएकाधिक हार्डलिंक केवल एक बार गिनता है)।

सादे के साथ सबसे महत्वपूर्ण अंतर du -sbयह है कि पुनरावर्ती duभी निर्देशिकाओं के आकार को गिनता है, जो अलग-अलग फाइल सिस्टम द्वारा अलग-अलग रिपोर्ट किए जाते हैं; इससे बचने के लिए, findकमांड का उपयोग केवल नियमित फाइल पास करने के लिए किया जाता है du। एक और अंतर यह है कि सीलिंक को अनदेखा किया जाता है (यदि उन्हें गिना जाना चाहिए, तो findकमांड को समायोजित किया जाना चाहिए)।

यह आदेश भी सादा और अधिक से अधिक स्मृति की खपत होगी du -sb, क्योंकि का उपयोग कर --files0-from=FILEबनाता है duदुकान उपकरण और की आईनोड संख्या सभी के रूप में एक से अधिक हार्ड लिंक के साथ ही फाइलों को याद के डिफ़ॉल्ट व्यवहार करने का विरोध किया, प्रोसेस की गई फ़ाइलें। (यह एक मुद्दा नहीं है यदि -lविकल्प का उपयोग हार्डलिंक को कई बार गिनने के लिए किया जाता है, क्योंकि डिवाइस को स्टोर करने और इनोड संख्याओं का एकमात्र कारण हार्डलिंक की गई फ़ाइलों को छोड़ना है जो पहले ही संसाधित हो चुके थे।)

यदि आप कुल आकार का एक मानव-पठनीय प्रतिनिधित्व प्राप्त करना चाहते हैं, तो केवल -hविकल्प जोड़ें (यह काम करता है क्योंकि duकेवल एक बार लागू किया जाता है और कुछ अन्य सुझाए गए उत्तरों के विपरीत कुल आकार की गणना करता है):

find . -type f -print0 | du -scbh --files0-from=- | tail -n 1

या (यदि आप चिंतित हैं कि कुछ प्रभाव -bफिर से ओवरराइड हैं -h)

find . -type f -print0 | du -sc --apparent-size -h --files0-from=- | tail -n 1

1
यह निश्चित नहीं है कि FreeBSD के लिए क्या करना है - हालांकि -bशायद इसके द्वारा प्रतिस्थापित किया जा सकता है -A -B 1, इसके लिए कोई समकक्ष नहीं है --files0-from=-, और xargsफ़ाइल लिस्ट ARG_MAX(मानव-पठनीय आउटपुट के लिए कुछ बाहरी समाधान) की तुलना में बड़ा होने पर कुछ वर्कअराउंड का उपयोग करने की आवश्यकता होगी ।
सर्गेई व्लासोव

4

बस एक विकल्प, का उपयोग कर ls:

ls -nR | grep -v '^d' | awk '{total += $5} END {print total, "Total"}'

ls -nR: -nपसंद करते हैं -l, लेकिन संख्यात्मक यूआईडी और जीआईडी ​​की -Rसूची बनाते हैं और पुनरावर्ती रूप से उपनिर्देशिका सूची देते हैं।

grep -v:गैर-मिलान लाइनों का चयन करने के लिए, मिलान की भावना को उल्टा करें। (-v POSIX द्वारा निर्दिष्ट किया गया है।) '^ d'निर्देशिकाओं को बाहर करेगा।

Ls कमांड: http://linux.about.com/od/commands/l/blcmdl1_ls.htm

मैन ग्रीप: http://linux.die.net/man/1/grep

संपादित करें :

सुझाव के रूप में संपादित किया गया @ सर्गेई व्लासोव।


का उपयोग -nकरने के लिए विकल्प lsके बजाय -l, (नाम के बजाय यूआईडी / GID नंबर दिखाने) सुरक्षित है क्योंकि उपयोगकर्ता और समूह नाम रिक्त स्थान शामिल कर सकते हैं (उदाहरण के लिए, यदि winbindया sssdएक Windows डोमेन के लिए प्रणाली में शामिल होने के लिए किया जाता है, आप की तरह समूह के नाम प्राप्त कर सकते हैं domain users) । उपयोगकर्ता और समूह नामों को देखने की आवश्यकता नहीं होने के कारण यह तेज़ होना चाहिए।
सर्गेई व्लासोव

धन्यवाद, यह खोजने के लिए की तुलना में तेजी से बहुत है ls!
गॉफोथियर

3

यदि आप चाहते हैं कि फ़ाइलों का आकार, उस स्थान को छोड़कर जो निर्देशिका उठाती है, तो आप कुछ ऐसा कर सकते हैं

find . -type f -print0 | xargs -0 du -scb | tail -n 1

@SergeyVlasov ने बताया कि यदि आपके पास इससे अधिक फाइलें हैं तो यह विफल हो जाएगा argmax। इससे बचने के लिए आप कुछ का उपयोग कर सकते हैं जैसे:

find . -type f -exec du -sb '{}' \; | gawk '{k+=$1}END{print k}'

1
यह आदेश चुपचाप एक गलत परिणाम दे देंगे अगर निर्देशिका है कि वे execve पर सीमा में फिट नहीं है () तर्क आकार इतने सारे फ़ाइलें हैं - इस मामले में xargsलागू करेगा duकई बार, और प्रत्येक मंगलाचरण बस इसके भाग के लिए महायोग प्रिंट होगा पूरी फ़ाइल सूची के बाद, tailअंतिम भाग का कुल आकार दिखाएगा।
सर्गेई व्लासोव

1
@SergeyVlasov अच्छा बिंदु, मैं उस के बारे में सोचा नहीं था, धन्यवाद, जवाब अद्यतन।
टेराडॉन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.