Ls *, ls ** और ls *** का परिणाम


86

मुझे पता है कि कमांड का उपयोग करके lsसभी निर्देशिकाओं को सूचीबद्ध किया जाएगा। लेकिन ls *कमांड क्या करता है? मैंने इसका उपयोग किया और यह केवल निर्देशिकाओं को सूचीबद्ध करता है। क्या स्टार के सामने lsइसका मतलब यह है कि यह निर्देशिकाओं को कितनी गहरी सूची दे सकता है?

जवाबों:


155

lsनिर्देशिकाओं की फ़ाइलों और सामग्री को सूचीबद्ध करता है, इसे तर्कों के रूप में पारित किया जाता है, और यदि कोई तर्क नहीं दिया जाता है, तो यह वर्तमान निर्देशिका को सूचीबद्ध करता है। यह कई विकल्पों को भी पारित कर सकता है जो इसके व्यवहार को प्रभावित करते हैं ( man lsविवरण के लिए देखें)।

यदि lsएक तर्क को पारित किया जा रहा है *, तो इसे *वर्तमान निर्देशिका में कॉल की गई फ़ाइल या निर्देशिका के लिए देखा जाएगा और इसे किसी अन्य की तरह सूचीबद्ध किया जाएगा। किसी अन्य की तुलना में किसी अन्य तरीके से चरित्र का lsइलाज नहीं करता है *

लेकिन अगर ls *एक है खोल कमांड लाइन है, तो खोल कि विस्तार होगा *करने के लिए इसी खोल के अनुसार ग्लोबिंग (भी रूप में जाना जाता फ़ाइल नाम पीढ़ी या फ़ाइल नाम विस्तार नियम)।

जबकि विभिन्न गोले विभिन्न ग्लोबिंग ऑपरेटरों का समर्थन करते हैं, उनमें से अधिकांश सरलतम पर सहमत होते हैं **एक पैटर्न के रूप में, वर्णों की संख्या का मतलब है ताकि *के रूप में एक globमौजूदा निर्देशिका है कि उस स्वरूप से मेल खाते में फ़ाइलों की सूची में विस्तार होगा। हालांकि एक अपवाद है कि एक .फ़ाइल नाम में एक प्रमुख बिंदु ( ) चरित्र को स्पष्ट रूप से मिलान किया जाना है, इसलिए *वास्तव में उन फ़ाइलों और निर्देशिकाओं की सूची में फैलता है जो .(लेक्सिकोग्राफ़िक क्रम में) से शुरू नहीं होती हैं ।

उदाहरण के लिए, यदि वर्तमान निर्देशिका फ़ाइलों कहा जाता है ., .., .foo, -lऔर foo bar, *खोल से दो तर्क करने के लिए विस्तारित किया जाएगा करने के लिए पारित करने के लिए ls: -lऔर foo bar, तो यह रूप में कि आप लिखकर हो जाएगा:

ls -l "foo bar"

या

'ls' "-l" foo\ bar

जो एक ही कमांड को चलाने के तीन तरीके हैं। सभी 3 मामलों में, lsकमांड (जो संभवतः /bin/lsउल्लिखित निर्देशिकाओं के एक लुकअप से निष्पादित की $PATHजाएगी) उन 3 तर्कों को पारित किया जाएगा: "ls", "-l" और "फू बार"।

संयोग से, इस मामले में, विकल्प के रूप lsमें पहली (सख्ती से बोलने वाला दूसरा ) का व्यवहार करेगा ।

अब, जैसा कि मैंने कहा, अलग-अलग गोले के अलग-अलग ग्लोबिंग ऑपरेटर हैं। कुछ दशक पहले, संचालक को zshप्रस्तुत किया गया था **/जिसका अर्थ है कि किसी भी स्तर की उपनिर्देशिका का मिलान करना, लघु के लिए (*/)#और ***/जो एक ही है सिवाय इसके कि यह निर्देशिकाओं को उतारते समय सहानुभूति का अनुसरण करता है।

कुछ साल पहले (जुलाई 2003 ksh93o+), ksh93ने उस व्यवहार को कॉपी करने का फैसला किया , लेकिन इसे वैकल्पिक बनाने का फैसला किया, और केवल **मामले को कवर किया (नहीं ***)। इसके अलावा, जबकि **अकेले विशेष नहीं था zsh(बस *अन्य पारंपरिक गोले की तरह ही मतलब था क्योंकि **किसी भी संख्या में वर्णों की संख्या का मतलब है), ksh93 में, **इसका मतलब वही है **/*(इसलिए किसी भी फ़ाइल या निर्देशिका के नीचे एक वर्तमान (छिपी हुई फाइलों को छोड़कर)।

bashकी नकल की ksh93कुछ साल बाद (फरवरी 2009, बैश 4.0), उसी सिंटैक्स लेकिन एक दुर्भाग्यपूर्ण अंतर के साथ: बैश की **तरह था zshकी ***जब उप-निर्देशिका में recursing यह सिमलिंक पीछा कर रहा था, कि है जो आम तौर पर नहीं है क्या आप यह कर करना चाहते हैं और बुरा साइड इफेक्ट हो सकता है। यह आंशिक रूप से bash-4.3 में तय किया गया था कि सहानुभूति अभी भी पीछा किया गया था, लेकिन पुनरावृत्ति वहाँ बंद कर दिया। यह पूरी तरह से 5.0 में तय किया गया था।

yash**2008 में संस्करण 2.0 में जोड़ा गया, extended-globविकल्प के साथ सक्षम किया गया । इसके कार्यान्वयन के करीब है zshकि में की **अकेले विशेष नहीं है। संस्करण 2.15 (2009) में, यह अपने स्वयं के एक्सटेंशनों की ***तरह zshऔर दो में जोड़ा गया है : .**और .***(जब zsh, D ग्लोब क्वालिफायर में **/*(D)) छिपी हुई फ़ाइलों और निर्देशिकाओं पर पुनर्विचार करते हुए छिपे हुए डायरियों को शामिल करना होगा, लेकिन यदि आप केवल छिपे हुए ट्रैवर्स को बदलना चाहते हैं dirs लेकिन छुपी हुई फ़ाइलों का विस्तार नहीं, आपको आवश्यकता है ((*|.*)/)#*या **/[^.]*(D))।

मछली खोल भी समर्थन करता है **। पहले के संस्करण की तरह bash, यह डायरेक्टरी ट्री के नीचे उतरते समय सहजीवन का अनुसरण करता है। उस शेल में हालांकि **/*ऐसा नहीं है ****अधिक है *कि कई निर्देशिकाओं का विस्तार कर सकते हैं। में fish, **/*.cसे मेल खाएगी a/b/c.cलेकिन नहीं a.cहै, जबकि, a**.cसे मेल खाएगा a.cऔर ab/c/d.cऔर zshके **/.*उदाहरण के लिए लिखा जाना है .* **/.*। वहाँ, के ***रूप **में *इतनी के बाद के रूप में समझा जाता है **

tcshglobstarV6.17.01 (मई 2010) में एक विकल्प भी जोड़ा गया है **और यह ***ए और ला दोनों का समर्थन करता है zsh

तो में tcsh, bashऔर ksh93, (जब इसी विकल्प सक्षम है ( globstar)) या fish, **वर्तमान एक नीचे सभी फ़ाइलों और निर्देशिकाओं का विस्तार, और ***रूप में ही है **के लिए fish, एक सिमलिंक traversing **के लिए tcshके साथ globstar, और के रूप में ही *में bashऔर ksh93(यह यद्यपि असंभव नहीं है कि उन गोले के भविष्य के संस्करण भी सहानुभूति को पीछे छोड़ देंगे)।

ऊपर, आपने देखा होगा कि यह सुनिश्चित करने की आवश्यकता है कि किसी भी विकल्प के रूप में व्याख्या की गई है। उसके लिए, आप यह करेंगे:

ls -- *

या:

ls ./*

कुछ आदेश हैं ( lsजहां इसके लिए कोई फर्क नहीं पड़ता ) जहां दूसरा बेहतर है क्योंकि --कुछ फ़ाइलनामों के साथ भी विशेष रूप से व्यवहार किया जा सकता है। यह मामला है -सबसे पाठ उपयोगिताओं के लिए, cdऔर pushdऔर फ़ाइल नाम, जिनमें शामिल है =के लिए चरित्र awkउदाहरण के लिए। Prepending ./सभी तर्कों के लिए अपने विशेष अर्थ निकालता है (मामलों में कम से कम के लिए ऊपर उल्लेख किया है)।

यह भी ध्यान दिया जाना चाहिए कि अधिकांश शेल में कई विकल्प होते हैं जो ग्लोबिंग व्यवहार को प्रभावित करते हैं (जैसे कि डॉट फ़ाइलों को अनदेखा किया जाता है या नहीं, सॉर्टिंग ऑर्डर, अगर कोई मिलान नहीं है तो क्या करना है ...), में $FIGNOREपैरामीटर भी देखेंksh

इसके अलावा, हर खोल में लेकिन csh, tcsh, fishऔर zsh, अगर ग्लोबिंग पैटर्न किसी भी फ़ाइल से मेल नहीं खाता, पैटर्न एक अविस्तारित तर्क जो भ्रम की स्थिति है और संभवतः कीड़े का कारण बनता है के रूप में पारित कर दिया है। उदाहरण के लिए, यदि वर्तमान निर्देशिका में कोई ग़ैर-छिपी हुई फ़ाइल नहीं है

ls *

वास्तव lsमें दो तर्कों के साथ कॉल करेगा lsऔर *। और जैसा कि कोई फ़ाइल नहीं है, इसलिए किसी को *भी नहीं बुलाया गया है , आपको ls (शेल नहीं) से एक त्रुटि संदेश दिखाई देगा : जैसे ls: cannot access *: No such file or directory, जिसे लोगों को यह सोचने के लिए जाना जाता है कि यह lsवास्तव में ग्लब्स का विस्तार था।

इस तरह के मामलों में समस्या और भी बदतर है:

rm -- *.[ab]

यदि कोई *.aहै और न ही *.bमौजूदा निर्देशिका में फ़ाइल, तो आप एक फ़ाइल कहा जाता है को हटाने खत्म हो सकता है *.[ab]गलती से ( csh, tcsh, और zshएक रिपोर्ट करेंगे कोई मुकाबला त्रुटि और फोन नहीं होगा rm(और fishसमर्थन नहीं करता [...]वाइल्डकार्ड))।

आप एक शाब्दिक पारित करने के लिए चाहते हैं, तो *करने के लिए ls, आपको लगता है कि उद्धृत करने के लिए है *के रूप में किसी तरह से चरित्र ls \*या ls '*'या ls "*"। POSIX- जैसे गोले में, ग्लोबिंग को पूरी तरह से उपयोग करके अक्षम किया जा सकता है ( set -o noglobया set -fबाद में zshजब तक sh/ kshएमुलेशन में काम नहीं कर रहा है )।


¹ जब (*/)#हमेशा समर्थन किया गया था, तो इसे पहले ..../zsh-2.0 (और संभावित रूप से पहले) के रूप में पहले शॉर्ट-हैंड किया गया था , फिर ****/2.1 में इसका निश्चित रूप प्राप्त करने से पहले 2.1 **/में (1992 की शुरुआत में)


22
वास्तव में महान जवाब!
एंड्रिया कोरबेलिनी

7
एक और अच्छा उदाहरण है find -name *। विशेष रूप से अधिक जटिल पैटर्न के साथ, यदि वर्तमान निर्देशिका में ठीक एक मैच है, तो लोग अक्सर महसूस नहीं करेंगे कि वे तारांकन पास नहीं कर रहे हैं find
njsg

मैं +1 देना जारी रखता हूं, मैं स्टीफन चेज़लस को यहां unix.stackexchange.com पर सक्रिय देखकर बहुत खुश हूं ! महान योगदान, स्टीफन हमेशा की तरह!
दिमित्रे रादौलोव

1
मछली में, *.[ab]सब कुछ खत्म करने की कोशिश करेगा .[ab][मछली में विशेष नहीं है।
कोनराड बोरोस्की

35

कमांड lsडिफॉल्ट करती है ls .: वर्तमान निर्देशिका में सभी प्रविष्टियों को सूचीबद्ध करें

कमांड का ls *अर्थ है ' *शेल पैटर्न के विस्तार पर रन एलएस '

*पैटर्न खोल द्वारा कार्रवाई की, और उन है कि एक के साथ शुरू छोड़कर, वर्तमान निर्देशिका में सभी प्रविष्टियों के लिए विस्तारित किया गया है .। यह एक स्तर गहरा जाएगा।

डबल या ट्रिपल *पैटर्न की व्याख्या उपयोग किए गए वास्तविक शेल पर निर्भर करती है।

*एक वाइल्डकार्ड है जो 0 या अधिक वर्णों से मेल खाता है। कुछ आधुनिक गोले **पैटर्न को देखकर उपनिर्देशिकाओं में पुनरावृत्ति करेंगे ।


17
सिवाय इसके कि अतिरिक्त * कुछ जोड़ें, ग्लोबस्टार को समझाते हुए अन्य उत्तर देखें। यह भी स्पष्ट किया जाना चाहिए कि ls का तारांकन से कोई लेना- देना नहीं है, यह कभी भी इनमें से किसी भी तारांकन से नहीं गुजरा है। भागो echo ls *को देखने के लिए जब आप लिखते हैं क्या निष्पादित किया जाएगा ls *
njsg

12

आप पहले की echoबजाय टाइप करके पूरी प्रक्रिया को ध्वस्त कर सकते हैं ls, यह देखने के लिए कि कमांड का विस्तार क्या है:

$ echo *
Applications Downloads Documents tmp.html

तो इस मामले में, ls *विस्तार करने के लिएls Applications Downloads Documents tmp.html

$ echo **
Applications Downloads Documents tmp.html

$ echo ***
Applications Downloads Documents tmp.html

तो कोई बदलाव नहीं। यह मानता है कि आप bashअपने शेल के रूप में उपयोग कर रहे हैं - ज्यादातर लोग हैं, और अलग-अलग गोले का व्यवहार अलग-अलग है। आप उपयोग कर रहे हैं ashया cshया kshया zsh, आप कुछ अलग काम करने की उम्मीद कर सकते हैं। यह अलग-अलग गोले होने की बात है।

तो कुछ अलग करने की कोशिश करते हैं (फिर भी bash) तो हमें ग्लोबिंग ( *) ऑपरेटर का एक विचार मिलता है जो हमारे लिए कर सकता है। उदाहरण के लिए, हम नाम के भाग के अनुसार फ़िल्टर कर सकते हैं:

$ echo D*
Downloads Documents

और दिलचस्प बात यह है कि एक अनुगामी स्लैश किसी भी निर्देशिका नाम का एक अंतर्निहित हिस्सा है। तो */केवल निर्देशिका (और निर्देशिकाओं के प्रतीकात्मक लिंक) निकलेंगे:

$ echo */
Applications/ Downloads/ Documents/

और हम बीच में स्लैश डालकर कई स्तरों पर कुछ फ़िल्टरिंग कर सकते हैं:

$ echo D*/*/
Documents/Work/ /Documents/unfinished/

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

$ ls -l /home/*/public_html/wp-config.php

यह सूची, यदि कोई हो, सभी wp-config.phpफाइलें जो किसी भी उपयोगकर्ता की public_htmlनिर्देशिका के आधार स्तर पर मौजूद हैं । या शायद अधिक पूर्ण होने के लिए:

$ find /home/*/public_html/ -name wp-config.php

यह किसी भी मिलेगा wp-config.phpकिसी भी उपयोगकर्ता के में फाइल public_htmlनिर्देशिका या उनके उपनिर्देशिका के किसी भी, लेकिन यह सिर्फ अधिक कुशलता से संचालित होगा find /home/ -name wp-config.php, क्योंकि यह कुछ भी जांच नहीं होगी लेकिनpublic_html उन में से प्रत्येक के लिए निर्देशिका।


1
"यह मानता है कि आप bashअपने शेल के रूप में उपयोग कर रहे हैं " using और ग्लोबस्टार सक्षम नहीं है। shopt -s globstarऔर इसे फिर से आज़माएं ...
njsg

ध्वस्त करने का एक और तरीका है, set -xजो हर बार निष्पादित "वास्तविक" कमांड को प्रिंट करना शुरू कर देगा (बंद हो जाएगा set +x)।
श्रीवत्सआर

10

globstarसक्षम किए गए विकल्प के साथ बैश 4.x सहित कुछ गोले में, **एक पुनरावर्ती ग्लोब प्रदर्शन करेंगे, मिलान निर्देशिकाओं को उतारेगा। अतिरिक्त तारांकन इस ऑपरेशन को और संशोधित नहीं करते हैं।


1
के रूप में मैं अपने जवाब में कहा कि हालांकि, के विपरीत सावधान रहना ksh93और zsh, bashप्रत्यावर्तन जो आम तौर पर अवांछित है में पार सिमलिंक करता है।
स्टीफन चेज़लस

यह अब बैश 4.3
स्टीफन चेज़लस

1

यदि आप "गहरा डुबकी" लगाना चाहते हैं, तो ls -R (पुनरावर्ती) विकल्प का उपयोग करें, या खोज का उपयोग करें, जैसे:

find . -ls

"खोजें" डायरेक्टरी ट्री के नीचे तक डुबकी लगाएगा (जैसा कि 'ls -R' होगा), और कई और विकल्प हैं, जैसे लिस्टिंग डायरेक्टरी (-Type d), केवल फाइलें (-type f) या अन्य होने वाली फाइलों को दिखाना विशेषताएँ (कोई उपयोगकर्ता नहीं / आदि / पासवार्ड, विशिष्ट अनुमतियाँ और एक पूरी बहुत अधिक)। "खोज" स्क्रिप्टिंग में कुछ हद तक सुरक्षित है (गोले के बीच असंगत ग्लोबिंग नियमों के कारण, साथ ही साथ डैश, आदि वाली फ़ाइलों के लिए विशेष पलायन)।

शेल वाइल्डकार्ड ग्लोबिंग डॉटफ़ाइल्स पर सिर्फ एक तारांकन '*' के साथ काम नहीं करेगा। केवल dotfiles को सूचीबद्ध करने के लिए, उपयोग करें:

ls .??*


-1

अतिरिक्त * गहराई स्तर नहीं जोड़ता है। लेकिन अगर आप कोशिश करते हैं

 ls */*/*

- आप वर्तमान फ़ोल्डर में फ़ोल्डर्स में सबफ़ोल्डर के सबफ़ोल्डर्स की सूची प्राप्त करेंगे ...


गलत। शेल के आधार पर, अतिरिक्त *एस गहराई स्तर जोड़ देगा।
njsg

तो क्या खोल अतिरिक्त सितारों पर गहराई का स्तर जोड़ देगा?
VB9-UANIC

कई। bashग्लोबस्टार विकल्प के साथ जीएनयू सहित , कोर्न शेल और ज़श। और संभवतः अन्य, मैं अनुमान लगाऊंगा। unix.stackexchange.com/a/62665/14831
njsg

-1

मेरी मुख्य पकड़ यह है कि गूंज ** / *। Ext आमतौर पर ...

मई या नहीं: वर्तमान निर्देशिका में .ext फ़ाइल सूचीबद्ध करें

मई या मई: शामिल नहीं। *

आम तौर पर मैं ग्लोब एक्सप्रेशन को which ** / ’कहना पसंद करूंगा और इसके परिणामस्वरूप अशक्त स्ट्रिंग (कोई उप-निर्देशिका) नहीं हो सकती। इस तरह से मैं प्रोग्राम इनपुट में ग्लोब एक्सप्रेशन को परिवर्तित करता हूं। बेशक, मैं यह सुनिश्चित करता हूं कि उपयोग के उदाहरणों में यह समझाने वाली टिप्पणियां हैं।

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