ls -d भी फाइलों को सूचीबद्ध क्यों करता है, और यह कहां से प्रलेखित है?


48
  • ls --directory a*यह निर्दिष्ट करते समय केवल निर्देशिकाओं को सूचीबद्ध करना चाहिएa*
  • लेकिन यह फाइलों और निर्देशिकाओं को सूचीबद्ध करता है a

प्रश्न :

  • मुझे इस पर कुछ प्रलेखन कहाँ मिल सकता है, इसके अलावा manऔर infoजहाँ मुझे लगता है कि मैंने अच्छी तरह से देखा?
  • क्या यह केवल BASH में काम करता है?


5
echo a*a(यदि कोई हो) के साथ शुरू होने वाली फ़ाइलों को भी सूचीबद्ध करेगा । बस इसे और अधिक स्पष्ट करने के लिए कि यह यह नहीं lsबल्कि बैश है।
ash108

जवाबों:


89

a*और *a*वाक्य रचना खोल द्वारा कार्यान्वित किया जाता, द्वारा नहीं lsआदेश।

जब आप टाइप करें

ls a*

आपके शेल प्रॉम्प्ट पर, शेल a*मौजूदा निर्देशिका में उन सभी फ़ाइलों की सूची में विस्तारित होता है, जिनके नाम से शुरू होता है a। उदाहरण के लिए, यह a*अनुक्रम तक विस्तारित हो सकता है a1 a2 a3, और उन्हें तर्क के रूप में पारित कर सकता है lslsआदेश अपने आप कभी नहीं देखता *चरित्र; यह केवल तीन तर्कों को देखता है a1, a2और a3

वाइल्डकार्ड विस्तार के प्रयोजनों के लिए, "फाइलें" वर्तमान निर्देशिका में सभी संस्थाओं को संदर्भित करती हैं। उदाहरण के लिए, a1एक सामान्य फ़ाइल a2हो सकती है, एक निर्देशिका हो सकती है, और a3एक सिमलिंक हो सकती है। उन सभी में निर्देशिका प्रविष्टियाँ हैं, और शेल के वाइल्डकार्ड विस्तार से यह परवाह नहीं है कि वे प्रविष्टियाँ किस प्रकार की इकाई को संदर्भित करती हैं।

व्यावहारिक रूप से सभी गोले आपके (bash, sh, ksh, zsh, csh, tcsh, ...) वाइल्डकार्ड लागू करने की संभावना है। विवरण अलग-अलग हो सकते हैं, लेकिन *शून्य या अधिक वर्णों के ?मिलान और किसी एक वर्ण से मेल खाने का मूल सिंटैक्स यथोचित संगत है।

विशेष रूप से बैश के लिए, यह बैश मैनुअल के "फाइलनाम विस्तार" अनुभाग में प्रलेखित है; info bash"फाइलनाम विस्तार" के लिए दौड़ें और खोजें, या यहाँ देखें ।

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

दूसरी ओर, कई फ़ाइलों का नाम बदलने के लिए एक कमांड लिखना मुश्किल है। यदि आप लिखते हैं:

mv *.log *.log.bak

यह संभवतः विफल हो जाएगा, क्योंकि *.log.bakमौजूदा निर्देशिका में पहले से मौजूद फ़ाइलों के आधार पर विस्तार किया गया है। ऐसे आदेश हैं जो इस तरह का काम करते हैं, लेकिन उन्हें यह निर्दिष्ट करने के लिए अपने स्वयं के सिंटैक्स का उपयोग करना होगा कि फ़ाइलों का नाम कैसे बदला जाए। कुछ कमांड (जैसे find) अपने स्वयं के वाइल्डकार्ड विस्तार कर सकते हैं; आपको शेल के विस्तार को दबाने के लिए तर्कों को उद्धृत करना होगा:

find . -name '*.txt' -print

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

mv *.log ..

यदि आप भूल जाते हैं ..:

mv *.log

और .logवर्तमान निर्देशिका में वास्तव में दो फाइलें होंगी, इसका विस्तार होगा:

mv one.log two.log

जिसका नाम बदलकर one.logलौंग रखा जाएगा two.log

संपादित करें : और 52 अपवोट्स के बाद, एक स्वीकार, और एक गुरु बिल्ला, शायद मुझे वास्तव में शीर्षक में सवाल का जवाब देना चाहिए।

-dया --directoryविकल्प के लिए lsकेवल निर्देशिका सूची यह नहीं बताता है। यह इसे निर्देशिका के रूप में खुद को सूचीबद्ध करने के लिए कहता है, न कि उनकी सामग्री पर। यदि आप एक निर्देशिका नाम को तर्क के रूप में देते हैं ls, तो यह निर्देशिका की सामग्री को सूचीबद्ध करेगा , क्योंकि आमतौर पर आप जिस चीज में रुचि रखते हैं। -dविकल्प इसे केवल निर्देशिका को सूचीबद्ध करने के लिए कहता है। वाइल्डकार्ड के साथ संयुक्त होने पर यह विशेष रूप से उपयोगी हो सकता है। यदि आप टाइप करते हैं:

ls -l a*

lsआपको प्रत्येक फ़ाइल की एक लंबी सूची देगा, जिसका नाम शुरू होता है a, और प्रत्येक निर्देशिका की सामग्री जिसका नाम शुरू होता है a। यदि आप फ़ाइलों और निर्देशिकाओं की एक सूची चाहते हैं, तो प्रत्येक के लिए एक पंक्ति, आप उपयोग कर सकते हैं:

ls -ld a*

जो इसके बराबर है:

ls -l -d a*

फिर से याद रखें कि lsकमांड कभी भी *चरित्र को नहीं देखता है ।

जहां तक ​​यह प्रलेखित है, man lsआपको lsकिसी भी यूनिक्स जैसी प्रणाली के बारे में कमांड के लिए प्रलेखन दिखाएगा । अधिकांश लिनक्स-आधारित सिस्टम पर, lsकमांड GNU कोरुटिल्स पैकेज का हिस्सा है; यदि आपके पास infoकमांड है, तो info lsया तो info coreutils lsआपको अधिक निश्चित और व्यापक दस्तावेज देना चाहिए। अन्य प्रणालियाँ, जैसे कि MacOS, lsकमांड के विभिन्न संस्करणों का उपयोग कर सकती हैं , और कमांड नहीं हो सकती हैं info; उन प्रणालियों के लिए, का उपयोग करें man ls। और यदि आप GNU कोरुटिल्स कार्यान्वयन का उपयोग कर रहे हैं तो अपेक्षाकृत कम उपयोग संदेश (मेरे सिस्टम पर 117 लाइनें) ls --helpदिखाएगा ।

और हां, यहां तक ​​कि विशेषज्ञों को अभी और फिर प्रलेखन से परामर्श करने की आवश्यकता है। इस क्लासिक मजाक को भी देखें ।


8
@Thomas: वर्तमान निर्देशिका में उनa* सभी फ़ाइलों की सूची में शामिल है, जिनके नाम से शुरू होता है a
कीथ थॉम्पसन

2
@ थोमस: या जो भी निर्देशिका आप निर्दिष्ट करते हैं:ls subdir/a*
कीथ थॉम्पसन

1
वास्तव में शेल विस्तार के बाद निष्पादित कमांड को देखने के लिए, echoयह। इसलिए यदि आप जानना चाहते हैं कि आप क्या कर रहे हैं ls a*, तो पहले निष्पादित करेंecho ls a*
कार्लोस कैंपडरो

1
या बस echo a*... शेल वैसे भी गोलाकार विस्तार करता है
बेकार

2
@sendmoreinfo: यह शेल और सेटिंग्स पर निर्भर करता है। Csh और tcsh में, एक असफल ग्लोब विस्तार एक त्रुटि है। बैश में, shopt -s failglobसमान व्यवहार का कारण बनता है। सेटिंग, nullglobलेकिन failglobकारण नहीं , उदाहरण के लिए, *nosuchfile*एक खाली स्ट्रिंग का विस्तार करने के लिए।
कीथ थॉम्पसन

27

कीथ थॉम्पसन का उत्तर देखें; लेकिन यह समझाने के लिए कि ls --directory a*फ़ाइलें और निर्देशिकाएँ क्यों दिखाई देती हैं : --directoryविकल्प गैर-निर्देशिका फ़ाइलों को दबाता नहीं है। इसके बजाय, यह निर्देशिकाओं को इस तरह सूचीबद्ध करता है, जबकि यह अन्यथा उनकी सामग्री को सूचीबद्ध करेगा। उदाहरण:

$ mkdir foo
$ touch foo/bar
$ ls foo
bar
$ ls --directory foo
foo

3
यह उदाहरण -Fविकल्प के साथ अधिक सम्मोहक है
ग्लेन जैकमैन

6

बहुत स्पष्ट होने के लिए, यह ls (1) मैनुअल पेज में प्रलेखित है :

-d, --directory सूची निर्देशिका प्रविष्टियों को सामग्री के बजाय, और प्रतीकात्मक लिंक को नहीं घटाएँ

निष्पक्ष होना, "सामग्री के बजाय प्रविष्टियाँ" शायद अधिक व्याख्यात्मक हो सकती हैं:

यदि FILE एक निर्देशिका है, तो उस निर्देशिका की सामग्री को सूचीबद्ध करने के बजाय निर्देशिका प्रविष्टि को ही दिखाएँ। यदि FILE एक प्रतीकात्मक लिंक है, तो लिंक द्वारा बताई गई फ़ाइल के बजाय लिंक प्रविष्टि को ही दिखाएँ।


पांडित्यपूर्ण होने के लिए, जबकि -d विकल्प को मैन पेज में समझाया जा सकता है (यदि थकाऊ), तो तर्क विस्तार और वाइल्डकार्डिंग को शेल मैन पेज में प्रलेखित नहीं किया जाता है क्योंकि यह शेल द्वारा किया गया है। यदि आपने अपने शेल में फ़ाइल नाम का विस्तार बंद कर दिया है, तो "ls a *" आपको केवल एक फाइल दिखाएगा, जिसका नाम सचमुच 'a' है।
जॉनी

पांडित्यपूर्ण होने के लिए, जबकि अन्य उत्तरदाताओं द्वारा शेल विस्तार का जवाब दिया गया था, उनमें से कोई भी स्पष्ट विवरण को संबोधित नहीं करता है और यह कैसे गलत हो सकता है। यदि आप मुझे दोहराना चाहते हैं, जो पहले से ही अच्छी तरह से कहा गया था, तो कृपया अधिक प्रत्यक्ष रहें।
एमएसडब्ल्यू

4

ग्लोबिंग

जैसा कि समझाया गया है, *(और इसी तरह के विस्तार) के विस्तार globको यूनिक्स शब्दजाल में बिंग कहा जाता है, और आमतौर पर कमांड प्रोसेसर की एक विशेषता होती है (जिसे यूनिक्स पार्लेंस में "शेल" के रूप में जाना जाता है)। तो ग्लोबिंग का उपयोग कई अन्य स्थानों पर भी किया जा सकता है; टाइप man 7 globएक क्लासिक Linux वितरण के खोल में (या देखना यह ) के बारे में अधिक के लिए globबिंग।

प्रारंभिक यूनिक्स में, globवास्तव में एक अलग कार्यक्रम के नाम से लागू किया गया था /etc/glob( उस के लिए प्रलेखन के लिए इस पुराने यूनिक्स मैनुअल के पृष्ठ 10 देखें )। आजकल, यह कोड पुस्तकालयों द्वारा आपूर्ति की जाने वाली एक कोड दिनचर्या है, और आमतौर पर इसका उपयोग गोले द्वारा किया जाता है। स्रोत : विकिपीडिया

निर्देशिकाएँ

के रूप में क्यों ls -dसूचियों के साथ ही निर्देशिका सूची ...

lsआदमी पेज कि ऐसा क्यों होता बताते हैं, लेकिन एक बहुत ही संक्षिप्त विवरण के साथ। तो यहाँ एक विस्तृत विवरण में एक प्रयास है:

डिफ़ॉल्ट रूप से उनके नाम दिए जाने पर निर्देशिकाओं lsकी सामग्री को सूचीबद्ध करता है , और निर्देशिकाओं के लिए सहानुभूति के लिए एक ही काम करेगा । -dविकल्प का मतलब है, (जो भी दिया जा सकता है "जब निर्देशिका (एँ) के नाम (रों) दिए गए" परोक्ष द्वारा globबिंग) , केवल निर्देशिका (एँ) के _name_s दिखाते हैं, लेकिन नहीं उनकी सामग्री। इसी प्रकार, जब निर्देशिकाओं के लिए सहानुभूति के स्पष्ट (स्पष्ट या निहित रूप से ) नाम (ओं) के साथ प्रदान किया जाता है, तो सहानुभूति का फ़ाइल नाम दिखाएं, न कि उस निर्देशिका की सामग्री जिसे वह संदर्भित करता है।

-dविकल्प लेना देना नहीं है, जहाँ तक मैं बता सकता हूँ के रूप में, के साथ जो आइटम सूचीबद्ध हैं; यह किया जा सकता है (स्रोत: यहां ) find, जैसे find . -maxdepth 1 -type d:। मुझे यकीन नहीं है कि केवल जीएनयू के साथ ऐसा करने का एक अच्छा तरीका है ls। कमांड का उपयोग करने के कुछ उदाहरण यहां दिए गए हैं find

तो योग करने के लिए: डिफ़ॉल्ट रूप lsसे निर्देशिकाओं की सामग्री को दिखाता है जब उनका पथ नाम दिया जाता है। -dइस व्यवहार को बदल देता है, केवल निर्देशिका नाम दिखा रहा है, जैसा कि एक मानक फ़ाइल के लिए किया जाएगा।


3

दस्तावेज़ीकरण यह नहीं कहता है कि यह केवल निर्देशिका प्रविष्टियों को सूचीबद्ध lsकरता है बल्कि जब निर्देशिका नाम प्राप्त करता है तो यह सामग्री के बजाय dir प्रविष्टि को सूचीबद्ध करता है। उदाहरण के लिए समझने का सबसे अच्छा तरीका है:

> {ice} ~ :10:47 % ls -l / 
total 97
drwxr-xr-x   2 root root  4096 May  3 00:27 bin
drwxr-xr-x   4 root root  1024 May  3 14:17 boot
drwxr-xr-x   2 root root  4096 Apr 29 13:44 cdrom
drwxr-xr-x  18 root root  4420 May  9 09:58 dev
...
lrwxrwxrwx   1 root root    33 May  3 14:16 vmlinuz -> boot/vmlinuz-3.9.0-030900-generic
lrwxrwxrwx   1 root root    29 May  3 11:07 vmlinuz.old -> boot/vmlinuz-3.8.0-19-generic
> {ice} ~ :10:47 % ls -ld /
drwxr-xr-x 25 root root 4096 May  3 14:16 /

2

प्रलेखन शेल का हिस्सा है । विशेष रूप से शेल एक कमांड निष्पादित करने से पहले एक विशेष क्रम में विभिन्न विस्तार और प्रतिस्थापन करता है ।

बॉर्न संगत शेल के लिए शब्द विस्तार का क्रम है

  1. टिल्ड विस्तार
  2. पैरामीटर विस्तार
  3. कमान प्रतिस्थापन
  4. अंकगणित विस्तार
  5. क्षेत्र विभाजन
  6. पथनाम विस्तार
  7. उद्धरण निकालना

इसलिए, lsकमांड *वर्णों को भी नहीं देखता है , तर्कों को पहले से ही a*ग्लोब पैटर्न से मेल खाती सभी फाइलों के साथ विस्तारित किया गया है । यह विंडोज पर विपरीत है, जहां प्रत्येक कमांड को ग्लोबबिंग की जरूरत है।


1

आपके लिए आवश्यक मुख्य शब्द man bash"पथनाम विस्तार" है।


3
अधिक "Pathname विस्तार" या "फ़ाइलनाम जेनरेशन"। "पैटर्न मिलान" से संबंधित है, लेकिन समान नहीं है।
स्टीफन चेज़लस

@StephaneChazelas वास्तव में, लेकिन "पैटर्न मिलान" मैन पेज में "pathname विस्तार" का एक उप-प्रकार है, जबकि "फ़ाइलनाम जेनरेशन" वहां बिल्कुल नहीं होता है (बस जानकारी दस्तावेज़ में)।
हॉके लैजिंग
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.