अनएक्सपेन्डेड तारांकन के कारण त्रुटियों से बचना


16

बैश में मैं अक्सर निम्नलिखित जैसे लूप्स का उपयोग करता हूं

for file in *.type; do 
  sommecommand "$file"; 
done;

सभी फाइलों के मिलान के लिए एक ऑपरेशन करने के लिए *.type। यदि इस समाप्ति के साथ कोई फ़ाइल कार्यशील निर्देशिकाओं में नहीं मिली है, तो तारांकन का विस्तार नहीं किया गया है और आमतौर पर मुझे एक त्रुटि संदेश मिलेगा जिसमें कहा जा रहा है कि somecommand फ़ाइल नहीं मिली। मैं तुरंत इस त्रुटि से बचने के कई तरीकों के बारे में सोच सकता हूं। लेकिन एक सशर्त जोड़ना बहुत सुरुचिपूर्ण नहीं लगता है। क्या इसे प्राप्त करने का एक छोटा और साफ तरीका है?

जवाबों:


20

हां, निम्नलिखित कमांड चलाएँ:

shopt -s nullglob

यह मैच को शून्य कर देगा और कोई त्रुटि उत्पन्न नहीं होगी।

  • यदि आप डिफ़ॉल्ट रूप से यह व्यवहार चाहते हैं, तो अपने में कमांड जोड़ें ~/.bashrc
  • यदि आप POSIX शेल में एक अशक्त ग्लोब का पता लगाना चाहते हैं, तो प्रयास करें

    for i in *.txt; do
      [ "$i" = '*.txt' ] && [ ! -e '*.txt' ] && continue
    done

Http://mywiki.wooledge.org/NullGlob देखें


1
ध्यान दें कि वास्तव में नामक एक फाइल होना संभव है *.txt। यह जाँच के लायक होगा कि क्या फ़ाइल मौजूद है।
क्रिस डाउन

तदनुसार पोस्ट किया गया।
गाइल्स क्वेनोट

@ क्रिसडाउन नोट करें कि आपके उत्तर पर भी यही टिप्पणी यहां लागू होती है ( breakइसके बजाय संभावित रूप से अधिक गंभीर परिणामों के कारण continue)।
स्टीफन चेज़लस 10

6

shopt -s nullglobयदि कोई मैच नहीं है, तो आप खाली सरणी में विस्तार करने के लिए उपयोग कर सकते हैं ।

बिना POSIX के गोले में nullglob, आप यह जाँच कर समस्या से बच सकते हैं कि जो फ़ाइलनाम पास किया जा रहा है वह वास्तव [ -e "$file" ] || [ -L "$file" ] || continueमें आपके forलूप के पहले भाग के रूप में मौजूद है ।


1
ध्यान दें कि यह कड़ाई से समकक्ष नहीं होगा क्योंकि [ -eदुर्गम फ़ाइलों या फ़ाइलों के लिए गलत वापस आ जाएगी जो कि अप्राप्य या अप्रमाणित फ़ाइलों के लिए सहानुभूति हैं।
स्टीफन चेज़लस

@StephaneChazelas, सहानुभूति के बारे में बिंदुओं को स्वीकार किया जाना चाहिए। लेकिन "दुर्गम फ़ाइलों" द्वारा आपके मन में क्या है? यहां तक ​​कि अगर मैं chmod 0 the_file, [ -e the_file ]अभी भी सच का मूल्यांकन करता हूं , तो यह कुछ और होना चाहिए।
डबियसजिम

1
टूटे हुए सिमिलिंक को संभालने के लिए एडिट सबमिट किया गया। आशा है कि यह ठीक है।
डबियसजिम

2
@dubiousjim, mkdir -p x/{a,b} && chmod 444 x && echo x/* && [ -e x/a ]। x / a दुर्गम है लेकिन जैसा कि x पठनीय है x / * का विस्तार होगा।
स्टीफन चेजलस

@ स्टेफ़ेनचेज़लस, महान, समझाने के लिए धन्यवाद।
डबियसजिम

4

एक nullglobविकल्प नहीं है कि गोले के लिए सामान्य तकनीक है

set -- [*].type *.type
case $1$2 in
  '[*].type*.type') shift 2;;
  *) shift
esac
for file do
  cmd  -- "$file"
done

अतिरिक्त [*].typeमामले को कवर करने के लिए है जहां *.typeवर्तमान निर्देशिका में एक फ़ाइल है ।

अब, यदि आप डॉट फाइलें शामिल करना चाहते हैं, तो यह अधिक जटिल हो जाती है

मुझे लगता है कि तकनीक कुछ साल पहले लौरे फेयरहेड द्वारा usenet पर गढ़ी गई थी।


0

find . -name '*.type' -maxdepth 0 -exec somecommand "{}" ";"

यह forलूप और शेल के ग्लोबिंग को समीकरण से पूरी तरह से हटा देता है । प्रति मैच एक बार कमांड findनिष्पादित करेगा -exec, और यदि कोई मैच नहीं हैं, तो इसे कभी भी निष्पादित नहीं किया जाएगा। -maxdepth 0निर्देश देता है (नाम पथ-तर्क के निदेशिकाओं में recurse नहीं कर पाते ., इस मामले में)।

नकारात्मक पक्ष यह है कि इसमें एक और एप्लिकेशन शामिल है, जो कि लगभग हर लिनक्स सिस्टम पर मौजूद है (और शायद सबसे यूनिक्स भी)।

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