"Du -sh *" और "du -sh//*" में क्या अंतर है?


26

बीच क्या अंतर है du -sh *और du -sh ./*?

नोट: मेरे *और ./*भागों में क्या हित हैं ।


2
उत्पादन ? एक आपको दिखाएंगे ।/ फ़ाइल नाम के सामने
कीवी

जवाबों:


69
$ स्पर्श ./c $ 'a \ n12 \ tb' फू
$ डुह *
0 ए
12 बी
0 फू ल
कुल ०

जैसा कि आप देख सकते हैं, -cफ़ाइल को एक विकल्प के रूप में लिया गया था duऔर रिपोर्ट नहीं किया गया है (और आप इसकी totalवजह से लाइन देखते हैं du -c)। इसके अलावा, नामक फ़ाइल a\n12\tbहमें यह सोचने पर मजबूर कर रही है कि क्या फ़ाइलें हैं aऔर कहा जाता है b

$ du -hs -- *
0       a
12      b
0       -c
0       foo

वह बेहतर है। कम से कम इस समय -cको एक विकल्प के रूप में नहीं लिया जाता है।

$ du -hs ./*
0       ./a
12      b
0       ./-c
0       ./foo

वह तो उससे भी बढ़िया है। ./उपसर्ग रोकता -cसे एक विकल्प और के अभाव के रूप में लिया जा रहा ./से पहले bमें उत्पादन इंगित करता कोई है कि वहाँ bवहाँ में फ़ाइल है, लेकिन वहाँ एक नई पंक्ति चरित्र के साथ एक फ़ाइल है (लेकिन नीचे देखें 1 उस पर आगे digressions के लिए)।

./यदि संभव हो तो उपसर्ग का उपयोग करना अच्छा है, और यदि नहीं और मनमाना डेटा के लिए, आपको हमेशा उपयोग करना चाहिए :

cmd -- "$var"

या:

cmd -- $patterns

यदि विकल्पों के अंत को चिह्नित करने का cmdसमर्थन नहीं करता है --, तो आपको इसे अपने लेखक को बग के रूप में रिपोर्ट करना चाहिए (जब यह पसंद से और इसके लिए प्रलेखित हो तो छोड़कर echo)।

ऐसे मामले हैं जहां ./*समस्याओं का समाधान --नहीं होता है। उदाहरण के लिए:

awk -f file.awk -- *

विफल रहता है अगर वहाँ एक फ़ाइल कहा जाता है a=b.txtवर्तमान निर्देशिका में (awk चर सेट aकरने के लिए b.txtफ़ाइल पर कार्रवाई करने के लिए इसे कह के बजाय)।

awk -f file.awk ./*

समस्या नहीं है क्योंकि ./aएक मान्य awk चर नाम ./a=b.txtनहीं है , इसलिए एक चर असाइनमेंट के रूप में नहीं लिया जाता है।

cat -- * | wc -l

यदि कोई फ़ाइल -वर्तमान निर्देशिका में कॉल की जाती है, तो विफल हो जाती है , क्योंकि यह catउसके स्टड से पढ़ने के लिए कहती है ( -ज्यादातर टेक्स्ट प्रोसेसिंग उपयोगिताओं और cd/ pushd) के लिए विशेष है।

cat ./* | wc -l

ठीक है क्योंकि ./-विशेष नहीं है cat

इस तरह की चीजें:

grep -l -- foo *.txt | wc -l

उन फ़ाइलों की संख्या को गिनने के लिए जिनमें fooगलत हैं क्योंकि यह मानती है कि फ़ाइल नाम में न्यूलाइन वर्ण नहीं हैं (नई फ़ाइल wc -lवर्ण, grepप्रत्येक फ़ाइल के लिए उन आउटपुट और फ़ाइल नाम में उन लोगों को गिना जाता है )। आपको इसके बजाय उपयोग करना चाहिए:

grep -l foo ./*.txt | grep -c /

( /वर्णों की संख्या गिनना अधिक विश्वसनीय है क्योंकि प्रति फ़ाइलनाम केवल एक ही हो सकता है)।

पुनरावर्ती के लिए grep, समान चाल का उपयोग करना है:

grep -rl foo .//. | grep -c //

./* हालांकि कुछ अवांछित दुष्प्रभाव हो सकते हैं।

cat ./*

प्रति फ़ाइल दो और चरित्र जोड़ता है, जिससे आप तर्कों के अधिकतम आकार + परिवेश तक जल्द ही पहुँच सकते हैं। और कभी-कभी आप नहीं चाहते कि ./आउटपुट में रिपोर्ट किया जाए। पसंद:

grep foo ./*

उत्पादन होगा:

./a.txt: foobar

के बजाय:

a.txt: foobar

आगे की खुदाई

1 है । मुझे ऐसा लगता है कि टिप्पणियों में चर्चा के बाद मुझे उस पर यहाँ विस्तार करना होगा।

$ du -hs ./*
0       ./a
12      b
0       ./-c
0       ./foo

ऊपर, कि ./प्रत्येक फ़ाइल की शुरुआत को चिह्नित करने का मतलब है कि हम स्पष्ट रूप से यह पहचान सकते हैं कि प्रत्येक फ़ाइल नाम कहां से शुरू होता है (पर ./) और कहां समाप्त होता है ( ./आउटपुट के अगले या अंत से पहले नई पंक्ति में )।

इसका मतलब यह है कि (के du ./*विपरीत, के उत्पादन du -- *) मज़बूती से पार्स किया जा सकता है, यद्यपि यह आसानी से एक स्क्रिप्ट में नहीं है।

जब आउटपुट एक टर्मिनल पर जाता है, तो बहुत सारे तरीके हैं जो फ़ाइल नाम आपको बेवकूफ बना सकते हैं:

  • नियंत्रण वर्ण, भागने के क्रम चीजों को प्रदर्शित करने के तरीके को प्रभावित कर सकते हैं। उदाहरण के लिए, \rकर्सर को लाइन की शुरुआत में \bले जाता है, कर्सर को पीछे ले जाता है, \e[Cआगे (अधिकांश टर्मिनलों में) ...
  • कई अक्षर सबसे स्पष्ट एक के साथ शुरू होने वाले एक टर्मिनल पर अदृश्य हैं: अंतरिक्ष चरित्र।
  • यूनिकोड वर्ण हैं जो ज्यादातर फोंट में स्लैश के समान हैं

    $ printf '\u002f \u2044 \u2215 \u2571 \u29F8\n'
    /    
    

    (देखें कि यह आपके ब्राउज़र में कैसे जाता है)।

एक उदाहरण:

$ touch x 'x ' $'y\bx' $'x\n0\t.\u2215x' $'y\r0\t.\e[Cx'
$ ln x y
$ du -hs ./*
0       ./x
0       ./x
0       ./x
0       .∕x
0       ./x
0       ./x

बहुत सारे हैं, xलेकिन yगायब है।

GNULs जैसे कुछ उपकरण गैर-मुद्रण योग्य वर्णों को एक प्रश्न चिह्न (ध्यान दें कि (U + 2215) प्रिंट करने योग्य है) के स्थान पर बदल देंगे, जब टर्मिनल पर आउटपुट जाता है। जीएनयू duनहीं करता है।

उन्हें स्वयं प्रकट करने के तरीके हैं:

$ ls
x  x   x?0?.∕x  y  y?0?.?[Cx  y?x
$ LC_ALL=C ls
x  x?0?.???x  x   y  y?x  y?0?.?[Cx

कैसे देखें में बदल गया ???के बाद हमें बताया lsहै कि हमारे चरित्र सेट ASCII था।

$ du -hs ./* | LC_ALL=C sed -n l
0\t./x$
0\t./x $
0\t./x$
0\t.\342\210\225x$
0\t./y\r0\t.\033[Cx$
0\t./y\bx$

$रेखा के अंत को चिह्नित करता है, इसलिए हम "x"बनाम को स्पॉट कर सकते हैं "x ", सभी गैर-मुद्रण योग्य वर्ण और गैर-एएससीआईआई अक्षर एक बैकस्लैश अनुक्रम द्वारा दर्शाए जाते हैं (बैकस्लैश खुद को दो बैकस्लैश के साथ दर्शाया जाएगा) जिसका अर्थ है कि यह अस्पष्ट है। यह GNU था sed, यह सभी POSIX अनुरूप sedकार्यान्वयनों में समान होना चाहिए लेकिन ध्यान दें कि कुछ पुराने sedकार्यान्वयन लगभग सहायक नहीं हैं।

$ du -hs ./* | cat -vte
0^I./x$
0^I./x $
0^I./x$
0^I.M-bM-^HM-^Ux$

(मानक नहीं बल्कि बहुत सामान्य, cat -Aकुछ कार्यान्वयन के साथ भी )। यह एक सहायक है और एक अलग प्रतिनिधित्व का उपयोग करता है लेकिन अस्पष्ट है ( "^I"और <TAB>उदाहरण के लिए इसे प्रदर्शित किया जाता है)।

$ du -hs ./* | od -vtc
0000000   0  \t   .   /   x  \n   0  \t   .   /   x      \n   0  \t   .
0000020   /   x  \n   0  \t   . 342 210 225   x  \n   0  \t   .   /   y
0000040  \r   0  \t   . 033   [   C   x  \n   0  \t   .   /   y  \b   x
0000060  \n
0000061

यह एक मानक और असंदिग्ध है (और कार्यान्वयन से कार्यान्वयन के अनुरूप) लेकिन पढ़ने में आसान नहीं है।

आप देखेंगे कि yऊपर कभी नहीं दिखा। यही कारण है कि पूरी तरह से असंबद्ध है मुद्दा साथ du -hs *कि फ़ाइल नाम के साथ कोई संबंध नहीं है लेकिन ध्यान दिया जाना चाहिए: क्योंकि duरिपोर्ट डिस्क उपयोग, यह (पहले से ही सूचीबद्ध एक फ़ाइल सब नहीं करने के लिए अन्य लिंक रिपोर्ट नहीं करता duकार्यान्वयन कि तरह व्यवहार करते हैं, हालांकि जब हार्ड लिंक सूचीबद्ध हैं कमांड लाइन पर)।


+1, अच्छा और पूरी तरह से (जहाँ तक मैं ^ ^ बता सकता हूँ)। मैं विशेष रूप से "grep -c /" लाभ से प्यार करता हूँ। यह भी ध्यान देने योग्य है: "*।" "ओवर" * का लाभ यूनिक्स FAQ (शायद faqs.org पर i) के एक (कई) अच्छे उत्तरों में से एक में प्रकट होता है। iirc, यह आरएम-आईएनजी फ़ाइलों के बारे में सवाल है। ए "-")।
ओलिवियर दुलाक

... और उनके नाम पर newlines और टैब के साथ फाइलें रखने के लिए यह बुरा अभ्यास नहीं है ? मुझे पता है कि मैं नामों को सीमित करने की कोशिश करता हूं[a-z0-9.+-]
ब्लैकलाइट शाइनिंग

5
@BlacklightShining, कारों को चुराना बहुत बुरा है, लेकिन अपनी कार को खुला छोड़ना बुरा है ( नए सिरे से अनदेखा करना), खासकर जब यह एक महंगी कार हो (संवेदनशील डेटा वाले सर्वर पर एक विशेषाधिकार प्राप्त उपयोगकर्ता के रूप में चलने वाली स्क्रिप्ट ...) या जब आप इसे किसी न किसी क्षेत्र में पार्क करें ( /tmpया बहुत महंगी कारों के साथ एक क्षेत्र $HOME) और यह एक प्रश्नोत्तर साइट पर जाने के लिए और भी बदतर है और कहें कि आपकी कार को बिना किसी स्थिति के निर्दिष्ट किए बिना लॉक करना ठीक है (लॉक गैरेज, स्क्रिप्ट में) आपने अपने आप से केवल एक मशीन पर चलाया है जो किसी नेटवर्क या रिमूवेबल स्टोरेज से कनेक्ट नहीं है ...)
स्टीफन चेज़लस

1
@ ब्लेकलाइटिंग, न्यूलाइन्स असामान्य हैं, लेकिन एम्बेडेड स्पेस आजकल बहुत आम हैं, खासकर GUI के माध्यम से बनाई गई फ़ाइलों के लिए।
एलेक्सिस

2
@BlacklightShining, हाँ, हालांकि वह (जैसे "b "या "a\bb") एक टर्मिनल पर एक उपयोगकर्ता को बेवकूफ बनाएगा, लेकिन इसके उत्पादन को पार्स करने वाली स्क्रिप्ट नहीं du ./*। मुझे शायद उसके बारे में एक नोट जोड़ना चाहिए। कल करेंगे। ध्यान दें कि पहले मुझे सामान्य अर्थों में विशेषाधिकार प्राप्त थे, न कि root(हालांकि rootपाठ्यक्रम के सभी अधिक लागू होते हैं )। newlines की अनुमति है, उन्हें अनदेखा करना एक बग है। कीड़े को शोषण की आदत है। आपको केस के आधार पर जोखिम को मापने के लिए मिला है। अच्छा कोडिंग अभ्यास कई मामलों में समस्याओं से बच सकता है। निश्चित रूप से एसई पर, हमें जागरूकता बढ़ानी चाहिए।
स्टीफन चेज़लस

6

वहाँ एक के बीच कोई अंतर है *और ./*क्या या तो इच्छा सूची फ़ाइलें के संदर्भ में। दूसरा अंतर केवल 2 फॉर्म के साथ होगा, प्रत्येक फाइल ./में उनके सामने एक डॉट स्लैश होगा, जो आमतौर पर वर्तमान निर्देशिका का मतलब है।

याद रखें कि .निर्देशिका वर्तमान निर्देशिका के लिए एक आशुलिपि संकेतन है।

$ ls -la | head -4
total 28864
drwx------. 104 saml saml    12288 Jan 23 20:04 .
drwxr-xr-x.   4 root root     4096 Jul  8  2013 ..
-rw-rw-r--.   1 saml saml      972 Oct  6 20:26 abcdefg

आप खुद को समझा सकते हैं कि इन 2 सूचियों को अनिवार्य रूप से एक ही बात है echoकि यह देखने के लिए कि शेल उन्हें क्या विस्तार देगा।

$ echo *
$ echo ./*

ये 2 कमांड आपकी वर्तमान निर्देशिका की सभी फाइलों को सूचीबद्ध करेगी।

उदाहरण

हम कुछ नकली डेटा बना सकते हैं जैसे:

$ touch file{1..5}
$ ll
total 0
-rw-rw-r--. 1 saml saml 0 Jan 24 07:14 file1
-rw-rw-r--. 1 saml saml 0 Jan 24 07:14 file2
-rw-rw-r--. 1 saml saml 0 Jan 24 07:14 file3
-rw-rw-r--. 1 saml saml 0 Jan 24 07:14 file4
-rw-rw-r--. 1 saml saml 0 Jan 24 07:14 file5

अब जब हम उपरोक्त echoकमांड का उपयोग करते हैं तो हमें निम्न आउटपुट दिखाई देते हैं:

$ echo *
file1 file2 file3 file4 file5
$ echo ./*
./file1 ./file2 ./file3 ./file4 ./file5

यह अंतर अनावश्यक लग सकता है, लेकिन ऐसी परिस्थितियां हैं, जहां आप विभिन्न यूनिक्स कमांड लाइन टूल्स की गारंटी देना चाहते हैं, जिन्हें आप कमांड लाइन के माध्यम से उनके लिए फाइलनाम पास कर रहे हैं, और अधिक कुछ नहीं!

तो फिर क्यों उपयोग ./*?

जैसा कि @ स्टीफन का जवाब बताता है कि यूनिक्स में फाइलों और निर्देशिकाओं के नामकरण के दौरान कौन से वर्ण कानूनी हैं, खतरनाक फाइलनामों का निर्माण किया जा सकता है, जो अप्रत्याशित दुष्प्रभाव होते हैं जब वे कमांड लाइन पर विभिन्न यूनिक्स कमांडों को पास करते हैं।

इसलिए अक्सर उपयोग का उपयोग ./गारंटी देने में मदद करने के लिए किया जाएगा कि विस्तारित फ़ाइलनाम को फ़ाइल नाम के रूप में माना जाता है जब विभिन्न यूनिक्स आदेशों के तर्क के रूप में पारित किया जाता है।

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