nullglob
विकल्प (जो BTW एक है zsh
आविष्कार, केवल करने के लिए साल बाद जोड़ा bash
( 2.0
मामलों की संख्या में आदर्श नहीं होगा))। और ls
एक अच्छा उदाहरण है:
ls *.txt
या इसके अधिक सही समकक्ष:
ls -- *.txt
साथ nullglob
पर चलाना शामिल है ls
कोई तर्क जो माना जाता है के साथ ls -- .
(वर्तमान निर्देशिका की सूची) यदि कोई फ़ाइल से मेल खाते हैं, जो शायद बुला से भी बदतर है ls
एक शाब्दिक साथ *.txt
तर्क के रूप में।
आपको अधिकांश पाठ उपयोगिताओं के साथ समान समस्याएं होंगी:
grep foo *.txt
foo
अगर कोई txt
फ़ाइल नहीं है, तो स्टड पर खोज करेंगे ।
एक अधिक समझदार डिफ़ॉल्ट, और csh, tsh, zsh या मछली 2.3+ (और शुरुआती यूनिक्स गोले) में से एक पूरी तरह से कमांड को रद्द करना है यदि ग्लोब मेल नहीं खाता है।
bash
(चूंकि संस्करण 3) में इसके लिए एक failglob
विकल्प है (इस चर्चा के लिए दिलचस्प ash
, एटी एंड टी के विपरीत ksh
या zsh
, bash
विकल्पों के लिए स्थानीय स्कोप का समर्थन नहीं करता है (हालांकि यह 4.4 में बदलना है), वह विकल्प जब वैश्विक स्तर पर सक्षम होता है तो कुछ चीजें टूट जाती हैं बाश-पूर्ण कार्यों की तरह)।
ध्यान दें कि csh और tshsh से भिन्न हैं zsh
, fish
या bash -O failglob
जैसे मामलों में:
ls -- *.txt *.html
जहाँ आपको कमांड को रद्द करने के लिए सभी ग्लोब को मैच नहीं करने की आवश्यकता है। उदाहरण के लिए, यदि एक txt फ़ाइल और कोई html फ़ाइल नहीं है, तो वह बन जाती है:
ls -- file.txt
आप के साथ जो व्यवहार प्राप्त कर सकते हैं zsh
साथ setopt cshnullglob
ही यह में करने के लिए एक अधिक समझदार रास्ते zsh
की तरह एक ग्लोब उपयोग करने के लिए होगा:
ls -- *.(txt|html)
में zsh
और ksh93
, आप भी आवेदन कर सकते हैं nullglob एक प्रति ग्लोब आधार है, जो एक वैश्विक सेटिंग को संशोधित करने की तुलना में बहुत saner दृष्टिकोण है पर:
files=(*.txt(N)) # zsh
files=(~(N)*.txt) # ksh93
यदि कोई txt
फ़ाइल त्रुटि के साथ कमांड को विफल करने के बजाय (या इसे *.txt
अन्य शेल के साथ एक शाब्दिक तर्क के साथ एक सरणी बना रही है) तो एक खाली सरणी बनाएगा ।
fish
2.3 से पहले के संस्करण इस तरह काम करते हैं bash -O nullglob
लेकिन जब एक ग्लोब का कोई मुकाबला नहीं होता है तो इंटरेक्टिव होने पर चेतावनी देते हैं। 2.3 के बाद से, यह zsh
ग्लब्स को छोड़कर for
, set
या में इस्तेमाल किए गए की तरह काम करता है count
।
अब, इतिहास नोट पर, व्यवहार वास्तव में बॉर्न शेल द्वारा तोड़ दिया गया था । यूनिक्स के पूर्व संस्करणों में, ग्लोबिंग /etc/glob
सहायक के माध्यम से किया गया था और सहायक ने ऐसा व्यवहार किया था csh
: यह कमांड को विफल कर देगा यदि कोई भी ग्लोब किसी भी फाइल से मेल नहीं खाता और ग्लब्स को बिना किसी मैच के हटा दें।
तो आज हम जिस स्थिति में हैं, वह बॉर्न शेल में किए गए एक बुरे निर्णय के कारण है।
ध्यान दें कि बॉर्न शेल (और सी शेल) एक और नई यूनिक्स सुविधा के साथ आया था: पर्यावरण। इसका मतलब था कि वैरिएबल एक्सपेंशन (यह पूर्ववर्ती ही था $1
, $2
... स्थितिगत मापदंडों)। बॉर्न शेल ने कमांड प्रतिस्थापन भी पेश किया।
बॉर्न शेल का एक और खराब डिज़ाइन निर्णय चर और कमांड प्रतिस्थापन के विस्तार पर ग्लोबिंग (और विभाजन) करना था (संभवतः थॉम्पसन शेल के साथ पिछड़े संगतता के लिए जहां echo $1
अभी भी सम्मिलित होगा /etc/glob
अगर $1
इसमें वाइल्डकार्ड शामिल थे (यह पूर्व प्रोसेसर मैक्रो विस्तार की तरह था) वहाँ, जैसा कि विस्तारित मूल्य में शेल कोड के रूप में फिर से पार्स किया गया था))।
मेल नहीं खाने वाले ग्लब्स का उदाहरण होगा कि:
pattern='a.*b'
grep $pattern file
कमांड को विफल कर देगा (जब तक a.whateverb
कि वर्तमान निर्देशिका में कुछ फाइलें नहीं हैं )। csh
(जो परिवर्तनशील विस्तार पर ग्लोबिंग भी करता है) उस मामले में कमांड को विफल नहीं करता है (और मैं यह तर्क दूंगा कि वहां एक निष्क्रिय बग छोड़ने से बेहतर है, भले ही यह उतना अच्छा न हो जितना ग्लोबिंग बिल्कुल भी नहीं है zsh
)।