मैं उम्मीद कर रहा था कि मुझे कोई आउटपुट नहीं मिलेगा।
यदि nullglob
डिफ़ॉल्ट थे, तो कई कमांड काफी अप्रत्याशित रूप से व्यवहार करेंगे, क्योंकि यह (शायद दुर्भाग्य से) सामान्य है जो कमांड एक या एक से अधिक फ़ाइल नाम के तर्क की तुलना में गुणात्मक रूप से शून्य फ़ाइल नाम तर्कों के मामले का इलाज करते हैं ।
मान लीजिए कि आपने सक्षम किया है nullglob
( shopt -s nullglob
) और आप उस निर्देशिका में हैं जहाँ कोई फ़ाइल मेल नहीं खाती हैं *.txt
। फिर *.txt
वास्तव में कुछ भी नहीं करने के लिए विस्तार होगा - एक खाली क्षेत्र नहीं है, लेकिन कोई भी क्षेत्र नहीं है - जैसा कि आपने अपेक्षा की थी। लेकिन इसके ये परिणाम होंगे:
ls *.txt
वर्तमान निर्देशिका (छिपी हुई फ़ाइलों को छोड़कर) में सभी फ़ाइलों को सूचीबद्ध करेगा , क्योंकि ls
जब आप इसे कोई फ़ाइल नाम तर्क नहीं देते हैं, तो यही होता है।
cat *.txt
मानक इनपुट से पढ़ा जाएगा , क्योंकि जब cat
कोई फ़ाइल नाम तर्क नहीं है, तो ऐसा लगता है जैसे आप भाग गए cat -
। यदि अंतःक्रियात्मक रूप से चल रहा है, तो यह इनपुट की प्रतीक्षा में बैठता है। कई आदेश इस तरह से व्यवहार करते हैं।
cp *.txt dest/
त्रुटि के साथ विफल होगा cp: missing destination file operand after 'dest/'
। यह एक आपदा नहीं है, लेकिन यह भ्रामक है और संभवतः मूक सफलता से काफी अलग है।
file *.txt
, और शून्य फ़ाइल नाम तर्कों के मामले के लिए कोई विशेष व्यवहार के साथ विभिन्न अन्य कार्यक्रम , अभी भी एक त्रुटि या उपयोग संदेश के साथ विफल हो जाएगा जब कोई भी पारित नहीं होता है।
- यहां तक कि ऐसे मामले जो सहजता से महसूस करते हैं कि उन्हें काम करना चाहिए अक्सर नहीं होता। कुछ नहीं के बजाय
printf 'Got file: "%s"\n' *.txt
प्रिंट होगा Got file: ""
।
- की घटनाओं को उद्धृत करने के लिए दुर्घटना विफलता
*
, ?
है, और [
है कि नहीं कर रहे हैं खोल द्वारा विस्तारित किया जा करने के लिए अधिक बार स्पष्ट रूप से गलत परिणाम होगा, लेकिन तरीके कि यह पता लगाने के लिए मुश्किल हो सकता है में करना है। उदाहरण के लिए, यदि वर्तमान निर्देशिका में कोई फ़ाइल नाम के साथ शुरू नहीं हुआ है gedit
, तो apt list gedit*
(जहां apt list 'gedit*'
इरादा था) बस बन जाएगा apt list
और सभी उपलब्ध पैकेजों को सूचीबद्ध करेगा ।
इसलिए यह अच्छा है कि आपको यह व्यवहार बिना अनुरोध के नहीं मिलता है। संभवतः सबसे सामान्य व्यावहारिक स्थिति जो वास्तव में सरल nullglob
है for f in *.txt
। इस प्रश्न को भी देखें (जो सर्जियो कोलोडियाज़नी के उत्तर से जुड़ा हुआ है)।
इसका उत्तर देने के लिए कठिन प्रश्न failglob
यह है कि - यह एक ग्लोब को बढ़ाने के लिए एक विस्तार त्रुटि है जो किसी भी फाइल से मेल नहीं खाती - बैश में डिफ़ॉल्ट नहीं है। मेरा मानना है कि सर्गी कोलोडियाज़नी का जवाब सीधे-सीधे इसे संबोधित किए बिना भी इसका कारण है। विस्तार त्रुटि पैदा किए बिना unexpanding ग्लब्स को बनाए रखना (शायद दुर्भाग्य से) मानकीकृत व्यवहार है, और यह पारंपरिक भी है, और इस प्रकार अपेक्षित व्यवहार है। हालांकि बैश पूरी तरह से पॉसिंक-अनुरूप होने का प्रयास नहीं करता है जब तक कि यह नाम के साथ नहीं लगाया जाता है sh
या --posix
विकल्प पारित नहीं किया जाता है, इसके कई डिज़ाइन विकल्प तब भी जब POSIX मोड में सीधे POSIX का पालन नहीं होता है। उन्हें कुछ व्यवहार करना पड़ा, और उपयोगकर्ताओं की उम्मीदों के खिलाफ जाने से जुड़े डाउनसाइड्स हैं।
मुझे लगता है कि यह इस मामले का कम से कम ऐतिहासिक रूप से प्रभावशाली पहलू है इसलिए मैंने इसे अंतिम रूप से सहेजा है ... लेकिन यह ध्यान देने योग्य है कि nullglob
व्यवहार के बारे में कुछ वैचारिक रूप से कुछ अजीब है।
nullglob
पहली बार में सुरुचिपूर्ण लगता है क्योंकि, वाक्यात्मक रूप से , यह शून्य मिलान फ़ाइलों के मामले को एक, दो या किसी अन्य संख्या के मामले से अलग नहीं करता है। हम जो कमांड चलाते हैं, जो ग्लोब के लिए तर्कों में विस्तार करते हैं, ऊपर बताए अनुसार उनका इलाज नहीं करते हैं। लेकिन वाक्यात्मक रूप से यह कम से कम सही लगता है, जो मुझे लगता है कि आपके प्रश्न के लिए प्रेरणा है।
और फिर भी, एक और, अधिक सूक्ष्म असंगति है जो nullglob
संबोधित नहीं करता है - कि यह वास्तव में बढ़ जाता है। शून्य ग्लोबिंग वर्ण ("वाइल्डकार्ड") के मामले को एक, या दो, या किसी अन्य संख्या से गहराई से अलग तरीके से व्यवहार किया जाता है। उदाहरण के लिए, shopt -s nullglob
यदि, ab?d?f
किसी फाइल से मेल नहीं खाता है , तो उसे हटा दिया जाता है; अगर ab?d
यह किसी भी फाइल से मेल नहीं खाता है, तो इसे हटा दिया जाता है; लेकिन अगर ab
वह किसी भी फाइल से मेल नहीं खाता (यानी, अगर कोई फाइल नहीं है जिसका नाम ठीक है ab
) तो भी उसे हटाया नहीं जाता है। बेशक, अगर इसे हटा दिया जाता है तो यह एक आपदा होगी, क्योंकि यह मौजूदा निर्देशिका में किसी मौजूदा फ़ाइल को संदर्भित करने का इरादा नहीं हो सकता है; हो सकता है कि वह किसी फ़ाइल का संदर्भ भी न दे। लेकिन यह अभी भी कुल स्थिरता के लिए किसी भी उम्मीद को खत्म करता है।
तीन बर्ताव प्रदान करने वाले बैश प्रदान करता है - ग्लब्स के उपचार का डिफ़ॉल्ट जो किसी भी फाइल से मेल नहीं खाता है, जैसे कि वे ग्लब्स नहीं थे और उन्हें अनएक्सपेन्डेड पास कर रहे थे, व्यवहार जो आप उनसे इलाज की उम्मीद करते थे (यदि आप वाक्यांश के इस विषम मोड़ को क्षमा कर देंगे) मेल करने वाली फ़ाइलों के सभी शून्य को इंगित करने के रूप में ( nullglob
), और उन्हें त्रुटियों पर विचार करने का सुरक्षित व्यवहार ( failglob
) - सभी शेल में निहित अस्पष्टता के लिए अलग-अलग दृष्टिकोणों का प्रतिनिधित्व करते हैं, यह जानने में सक्षम नहीं हैं कि क्या कोई विशेष शब्द एक होने का इरादा है फ़ाइल का नाम। शेल अपने विस्तार को इस बात के ज्ञान के बिना करता है कि आप इसके साथ विशेष कमांड कैसे कॉल करते हैं, उनके तर्कों का इलाज करेंगे।
यह चिंताओं के अलगाव के कई उदाहरणों में से एक है । उन प्रणालियों में जिनका डिज़ाइन यूनिक्स दर्शन का अनुसरण करता है, प्रत्येक भाग का उद्देश्य एक काम करना और इसे अच्छी तरह से करना है । शेल पाठ को आदेशों और तर्कों में संसाधित करता है और उन आदेशों को आमंत्रित करता है, जिनमें से अधिकांश शेल के लिए बाहरी हैं। यह उन व्यवस्थाओं की तुलना में बहुत अच्छा और अधिक बहुमुखी है जहां बाहरी कमांड खुद उन परिवर्तनों (डॉस और विंडोज में पारंपरिक कमांड प्रोसेसर के साथ) के प्रदर्शन के लिए जिम्मेदार हैं । लेकिन इसकी कभी-कभार गिरावट होती है।
shopt -s nullglob
बेजोड़ पैटर्न के लिए खाली तार निकलेगा औरshopt -u nullglob
(मानक सेटिंग) पैटर्न को ही उत्पन्न करेगा।