BASH: फॉर, व्हिल, टिल लूप का विवरण और उपयोग के उदाहरण। BASH स्क्रिप्ट में अनंत while लूप WHILE और UNTIL लूप

💖क्या आपको यह पसंद है?लिंक को अपने दोस्तों के साथ साझा करें

लेखक: पॉल कोबाउट
प्रकाशित तिथि: 16 अक्टूबर 2014
अनुवाद: ए पैनिन
अनुवाद दिनांक: 21 दिसंबर 2014

अध्याय 22. लिपियों में लूप्स

परीक्षण आदेश

परीक्षण कमांड आपको यह निर्धारित करने की अनुमति देता है कि कोई अभिव्यक्ति सत्य है या गलत। आइए परीक्षण से प्रारंभ करें कि पूर्णांक मान 10 पूर्णांक मान 55 से अधिक है या नहीं। $ परीक्षण 10 -gt 55 ; प्रतिध्वनि $? 1$

यदि अभिव्यक्ति गलत है तो परीक्षण कमांड 1 लौटाता है। और, जैसा कि आप निम्नलिखित उदाहरण में देखेंगे, यदि अभिव्यक्ति सत्य का मूल्यांकन करती है तो परीक्षण कमांड 0 लौटाएगा। $ टेस्ट 56 -जीटी 55 ; प्रतिध्वनि $? $0

यदि आप सही और गलत स्ट्रिंग के साथ काम करने में अधिक सहज हैं, तो आप नीचे दिखाए अनुसार परीक्षण कमांड का उपयोग कर सकते हैं। $ टेस्ट 56 -जीटी 55 && इको ट्रू || प्रतिध्वनि असत्य सत्य $ परीक्षण 6 -gt 55 && प्रतिध्वनि सत्य || प्रतिध्वनि मिथ्या असत्य

परीक्षण आदेश को बदला भी जा सकता है वर्ग कोष्ठक, इसलिए नीचे दिए गए उदाहरण के आदेश पूरी तरह से ऊपर के उदाहरण के आदेशों के समान हैं। $ [56 -gt 55 ] && प्रतिध्वनि सत्य || प्रतिध्वनि असत्य सत्य $ [6 -gt 55 ] && प्रतिध्वनि सत्य || प्रतिध्वनि मिथ्या असत्य

नीचे कुछ जाँचों के कार्यान्वयन के उदाहरण दिए गए हैं। इसके अवलोकन के लिए मैन टेस्ट पेज देखें अतिरिक्त सुविधाओंविभिन्न जाँचों का कार्यान्वयन। [ -d foo ] क्या निर्देशिका foo मौजूद है? [ -ई बार ] क्या बार फ़ाइल मौजूद है? [ "/etc" = $PWD ] क्या /etc $PWD के मान के बराबर है? [ $1 != "गुप्त" ] क्या पहले स्क्रिप्ट पैरामीटर का मान गुप्त स्ट्रिंग से भिन्न है? [55 -lt $bar ] क्या पूर्णांक मान 55 $bar के मान से कम है? [ $foo -ge 1000 ] क्या $foo का मान पूर्णांक मान 1000 से अधिक या उसके बराबर है? ["एबीसी"< $bar ] Будет ли строка abc расположена выше значения переменной $bar в списке после сортировки? [ -f foo ] Является ли foo обычным файлом? [ -r bar ] Является ли bar पढ़ने योग्य फ़ाइल? [ foo -nt bar ] क्या foo bar से नया है? [ -ओ संज्ञा ] क्या संज्ञा शेल विकल्प सक्षम है?

चेक ऑपरेटरों को संबंधित ऑपरेटरों के साथ जोड़ा जा सकता है तार्किक संचालन"और" और "या"। paul@RHEL4b:~$ [66 -gt 55 -a 66 -lt 500 ] && echo true || प्रतिध्वनि असत्य सत्य पॉल@RHEL4b:~$ [ 66 -gt 55 -a 660 -lt 500 ] && प्रतिध्वनि सत्य || प्रतिध्वनि असत्य असत्य पॉल@RHEL4b:~$ [66 -gt 55 -o 660 -lt 500 ] && प्रतिध्वनि सत्य || प्रतिध्वनि असत्य सत्य

सशर्त छलांग यदि नहीं तो

यदि तब अन्यथा निर्माण का उद्देश्य एक कोड विकल्प का चयन करना है। यदि कोई निश्चित शर्त सत्य है, तो कुछ कोड निष्पादित किया जाएगा, अन्यथा कुछ अन्य कोड निष्पादित किया जाएगा। नीचे दिया गया उदाहरण किसी फ़ाइल के अस्तित्व की जाँच करता है, जिसके बाद, यदि फ़ाइल के अस्तित्व की धारणा की पुष्टि हो जाती है, तो संबंधित संदेश प्रदर्शित होता है। #!/bin/bash यदि [ -f isit.txt ] तो फ़ाइल isit.txt मौजूद है को प्रतिध्वनित करें! अन्यथा इको फ़ाइल isit.txt नहीं मिली! फाई

यदि हम इस स्क्रिप्ट कोड को "पसंद" नामक फ़ाइल में सहेजते हैं, तो इसे उसी तरह निष्पादित किया जा सकता है। $ ./choice फ़ाइल isit.txt नहीं मिली! $ स्पर्श isit.txt $ ./choice फ़ाइल isit.txt मौजूद है! $

सशर्त छलांग यदि तब एलिफ

आप elif स्टेटमेंट का उपयोग करके किसी अन्य ब्लॉक के अंदर एक नया if स्टेटमेंट रख सकते हैं। ऐसी प्रविष्टि का एक सरल उदाहरण नीचे दिया गया है। #!/bin/bash count=42 यदि [ $count -eq 42 ] तो प्रतिध्वनि करें "42 एक वैध मान है।" एलिफ़ [ $गिनती -gt 42 ] फिर "बहुत अधिक" गूँजें। अन्यथा प्रतिध्वनि "पर्याप्त नहीं।" फाई

पाश के लिए

नीचे दिया गया उदाहरण बैश शेल में क्लासिक फॉर लूप का सिंटैक्स दिखाता है। 1 2 4 में आई के लिए इको $आई डन

इनलाइन शेल कॉल के साथ संयुक्त रूप से लूप का उपयोग करने का एक उदाहरण। #!/bin/ksh `seq 1 20` में काउंटर के लिए 1 से 20 तक इको गिनती करें, वर्तमान मूल्य $काउंटर स्लीप 1 हो गया

ऊपर प्रस्तुत स्क्रिप्ट के समान पूरी तरह से एक स्क्रिप्ट को मूल्यों की एक श्रृंखला (मूल्य से मूल्य तक) के लिए बैश शेल घोषणा का उपयोग करके एम्बेडेड कमांड शेल का उपयोग किए बिना बनाया जा सकता है। #!/bin/bash काउंटर के लिए (1..20) 1 से 20 तक इको गिनती करें, वर्तमान मूल्य $काउंटर स्लीप 1 हो गया

यह लूप पैटर्न द्वारा फ़ाइलों को खोजने के लिए एक तंत्र का उपयोग करता है (कमांड विस्तार तंत्र के भाग के रूप में कार्यान्वित)। यदि उपरोक्त निर्देश सीधे पोस्ट किए गए हैं कमांड लाइन, यह समान रूप से कार्य करेगा। *.ksh में फ़ाइल के लिए kahlan@solexp11$ ls count.ksh go.ksh kahlan@solexp11$; do cp $file $file.backup ; किया kahlan@solexp11$ ls count.ksh count.ksh.backup go.ksh go.ksh.backup

घुमाव के दौरान

थोड़ी देर के लूप का उपयोग करने का एक सरल उदाहरण नीचे दिया गया है। मैं=100; जबकि [ $i -ge 0 ] ; 100 से 0 तक प्रतिध्वनि उलटी गिनती करें, वर्तमान मूल्य $i; चलो मैं--; हो गया

अनंत लूप को while true या while: घोषणाओं का उपयोग करके कार्यान्वित किया जा सकता है, जहां प्रतीक: कोर्न शेल और बैश में लापता ऑपरेशन के बराबर है। #!/bin/ksh # अंतहीन लूप जबकि: इको हैलो स्लीप 1 हो गया

लूप तक

नीचे तक लूप का उपयोग करने का एक सरल उदाहरण दिया गया है। चलो मैं=100; जब तक [ $i -le 0 ] ; 100 से 1 तक प्रतिध्वनि उलटी गिनती करें, वर्तमान मूल्य $i; चलो मैं--; हो गया

अभ्यास: लिपियों में परीक्षण और लूप

3. एक स्क्रिप्ट विकसित करें जो 3 से 7 तक गिनती करने के लिए थोड़ी देर के लूप का उपयोग करेगी।

4. एक स्क्रिप्ट विकसित करें जो 8 से 4 तक गिनती करने के लिए एक जब तक लूप का उपयोग करेगी।

5. एक स्क्रिप्ट विकसित करें जो वर्तमान निर्देशिका में .txt एक्सटेंशन वाली फ़ाइलों की गिनती करेगी।

6. जेनरेट की गई स्क्रिप्ट में if स्टेटमेंट का उपयोग करें सही संचालनयदि वर्तमान निर्देशिका में .txt एक्सटेंशन वाली कोई फ़ाइलें नहीं हैं।

व्यावहारिक कार्य को पूरा करने की सही प्रक्रिया: स्क्रिप्ट में चेक और लूप

1. एक स्क्रिप्ट विकसित करें जो 3 से 7 तक गिनती करने के लिए फॉर लूप का उपयोग करेगी।

#!/bin/bash for i in 3 4 5 6 7 प्रतिध्वनि करें 3 से 7 तक गिनती, वर्तमान मान $i हो गया

2. एक स्क्रिप्ट विकसित करें जो 1 से 17000 तक गिनती करने के लिए फॉर लूप का उपयोग करेगी।

बैश शेल लूप के लिए समर्थन करता है, जो आपको मानों के अनुक्रमों पर पुनरावृति करने की अनुमति देता है। ऐसे लूपों की मूल संरचना इस प्रकार है:

सूची में var के लिए कमांड पूरा करें
लूप के प्रत्येक पुनरावृत्ति में, वेरिएबल var को अगले मान पर लिखा जाएगा सूची. इसलिए लूप का पहला पास सूची से पहले मान का उपयोग करेगा। दूसरे में - दूसरा, और इसी तरह - जब तक लूप अंतिम तत्व तक नहीं पहुंच जाता।

सरल मूल्यों पर पुनरावृत्ति

शायद बैश स्क्रिप्ट में लूप के लिए सबसे सरल उदाहरण सरल मानों की सूची पर पुनरावृत्ति करना है:

#!/bin/bash for var पहले दूसरे तीसरे चौथे पांचवें में echo करें $var आइटम पूरा हो गया
इस स्क्रिप्ट के परिणाम नीचे दिखाए गए हैं। आप स्पष्ट रूप से देख सकते हैं कि $var वैरिएबल में सूची से क्रमिक रूप से तत्व शामिल हैं। ऐसा तब तक होता है जब तक चक्र उनमें से अंतिम तक नहीं पहुँच जाता।


लूप के लिए सरल

कृपया ध्यान दें कि $var वैरिएबल लूप से बाहर निकलने पर अपना मान बरकरार रखता है, इसकी सामग्री को बदला जा सकता है, और सामान्य तौर पर, आप किसी भी अन्य वैरिएबल की तरह इसके साथ काम कर सकते हैं।

जटिल मूल्यों पर पुनरावृत्ति

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

#!/bin/bash var के लिए पहले "दूसरा" "तीसरा" "मैं यह करूँगा" इको करें "यह है: $var" हो गया
इस लूप के सूची से गुजरने के बाद यही होता है। जैसा कि आप देख सकते हैं, परिणाम काफी अपेक्षित है।


जटिल मूल्यों पर पुनरावृत्ति
TNW-CUS-FMP - हमारी सेवाओं पर 10% छूट के लिए प्रोमो कोड, 7 दिनों के भीतर सक्रियण के लिए उपलब्ध है"

कमांड के परिणामों से प्राप्त सूची के साथ एक लूप प्रारंभ करना

लूप को प्रारंभ करने का दूसरा तरीका इसे एक सूची पास करना है, जो एक कमांड का परिणाम है। यहां कमांड प्रतिस्थापन का उपयोग उन्हें निष्पादित करने और उनके कार्य के परिणाम प्राप्त करने के लिए किया जाता है।

#!/bin/bash file='myfile' for var in $(cat $file) do echo ' $var' made
यह उदाहरण कैट कमांड का उपयोग करता है, जो फ़ाइल की सामग्री को पढ़ता है। मानों की परिणामी सूची को लूप में पास किया जाता है और स्क्रीन पर प्रदर्शित किया जाता है। कृपया ध्यान दें कि जिस फ़ाइल तक हम पहुंच रहे हैं उसमें नई पंक्तियों द्वारा अलग किए गए शब्दों की एक सूची है; किसी रिक्त स्थान का उपयोग नहीं किया गया है।


एक लूप जो किसी फ़ाइल की सामग्री के माध्यम से घूमता है

यहां हमें यह ध्यान रखना चाहिए कि ऐसा दृष्टिकोण, यदि लाइन-बाय-लाइन डेटा प्रोसेसिंग अपेक्षित है, तो अधिक जटिल संरचना वाली फ़ाइल के लिए काम नहीं करेगा, जिसकी पंक्तियों में रिक्त स्थान से अलग किए गए कई शब्द हो सकते हैं। लूप व्यक्तिगत शब्दों को संसाधित करेगा, पंक्तियों को नहीं।

क्या होगा यदि यह वह नहीं है जिसकी आपको बिल्कुल आवश्यकता है?

फ़ील्ड विभाजक

उपरोक्त विशेषता का कारण विशेष है पर्यावरणपरिवर्ती तारक, जिसे IFS (आंतरिक फ़ील्ड विभाजक) कहा जाता है और आपको फ़ील्ड विभाजक निर्दिष्ट करने की अनुमति देता है। डिफ़ॉल्ट रूप से, बैश शेल निम्नलिखित वर्णों को फ़ील्ड विभाजक मानता है:
  • अंतरिक्ष
  • टैब वर्ण
  • पंक्ति फ़ीड वर्ण
यदि बैश को डेटा में इनमें से कोई भी वर्ण मिलता है, तो यह मान लिया जाता है कि यह सूची में अगले स्वतंत्र मान से पहले है।

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

आईएफएस=$"\n"
एक बार जब आप इस कमांड को अपनी बैश स्क्रिप्ट में जोड़ लेते हैं, तो यह अपेक्षा के अनुरूप काम करेगा, रिक्त स्थान और टैब को अनदेखा करेगा और केवल न्यूलाइन वर्णों को फ़ील्ड विभाजक के रूप में मानेगा।

#!/bin/bash file='/etc/passwd' IFS=$'\n' for var in $(cat $file) do echo '' $var' made
यदि यह स्क्रिप्ट चलाई जाती है, तो यह वही आउटपुट देगी जो इसके लिए आवश्यक है, लूप के प्रत्येक पुनरावृत्ति में, फ़ाइल में लिखी गई अगली पंक्ति तक पहुंच प्रदान करेगी।


फॉर लूप में फ़ाइल का लाइन दर लाइन ट्रैवर्सल

विभाजक अन्य पात्र भी हो सकते हैं। उदाहरण के लिए, ऊपर हमने /etc/passwd फ़ाइल की सामग्री प्रदर्शित की है। लाइनों पर उपयोगकर्ता डेटा को कोलन द्वारा अलग किया जाता है। यदि आपको ऐसी स्ट्रिंग्स को लूप में संसाधित करने की आवश्यकता है, तो IFS को इस तरह कॉन्फ़िगर किया जा सकता है:

किसी निर्देशिका में मौजूद फ़ाइलों को पार करना

बैश स्क्रिप्ट में लूप के लिए सबसे आम उपयोगों में से एक निर्देशिका में स्थित फ़ाइलों को पार करना और उन फ़ाइलों को संसाधित करना है।

उदाहरण के लिए, यहां फ़ाइलों और फ़ोल्डरों को सूचीबद्ध करने का तरीका बताया गया है:

#!/bin/bash फ़ाइल के लिए /home/likegeeks/* में करें यदि [ -d "$file" ] तो echo "$file एक निर्देशिका है" elif [ -f "$file" ] तो echo "$file एक है फ़ाइल" फाई हो गई
यदि आप लेखों की इस श्रृंखला में पिछली सामग्री को समझ गए हैं, तो आपको if-then निर्माण की संरचना को समझना चाहिए, साथ ही किसी फ़ाइल को फ़ोल्डर से कैसे अलग करना है। यदि आपको उपरोक्त कोड को समझना मुश्किल लगता है, तो इस सामग्री को दोबारा पढ़ें।

स्क्रिप्ट यही आउटपुट देगी.


किसी फ़ोल्डर की सामग्री प्रदर्शित करना

ध्यान दें कि हम लूप को कैसे प्रारंभ करते हैं, अर्थात् फ़ोल्डर पते के अंत में वाइल्डकार्ड "*"। इस प्रतीक को वाइल्डकार्ड के रूप में माना जा सकता है जिसका अर्थ है: "किसी भी नाम वाली सभी फ़ाइलें।" यह आपको पैटर्न से मेल खाने वाले फ़ाइल नामों के स्वचालित प्रतिस्थापन को व्यवस्थित करने की अनुमति देता है।

यदि कथन में किसी शर्त का परीक्षण करते समय, हम चर नाम को उद्धरण चिह्नों में संलग्न करते हैं। ऐसा इसलिए किया जाता है क्योंकि फ़ाइल या फ़ोल्डर नाम में रिक्त स्थान हो सकते हैं।

लूप के लिए सी-शैली

यदि आप सी प्रोग्रामिंग भाषा से परिचित हैं, तो लूप्स के लिए बैश का वर्णन करने का सिंटैक्स आपको अजीब लग सकता है, क्योंकि आप स्पष्ट रूप से लूप्स का इस तरह से वर्णन करने के आदी हैं:

(i = 0; i के लिए)< 10; i++) { printf("number is %d\n", i); }
बैश स्क्रिप्ट में आप लूप के लिए उपयोग कर सकते हैं, जिसका विवरण सी-स्टाइल लूप के समान दिखता है, हालांकि कुछ अंतर हैं। इस दृष्टिकोण के साथ चक्र आरेख इस प्रकार दिखता है:

के लिए ((वेरिएबल का प्रारंभिक मान; लूप समाप्त होने की स्थिति; वेरिएबल का परिवर्तन))
बैश में इसे इस प्रकार लिखा जा सकता है:

((ए = 1; ए के लिए)< 10; a++))
यहां एक कार्यशील उदाहरण दिया गया है:

#!/bin/bash for ((i=1; i<= 10; i++)) do echo "number is $i" done
यह कोड 1 से 10 तक की संख्याओं की एक सूची आउटपुट करेगा।

सी शैली में लूपिंग

घुमाव के दौरान

बैश स्क्रिप्ट में लूप को व्यवस्थित करने के लिए फॉर कंस्ट्रक्ट एकमात्र तरीका नहीं है। आप यहां while लूप का भी उपयोग कर सकते हैं। ऐसे लूप में, आप एक निश्चित स्थिति की जांच करने के लिए एक कमांड निर्दिष्ट कर सकते हैं और लूप के मुख्य भाग को तब तक निष्पादित कर सकते हैं जब तक कि परीक्षण की जा रही स्थिति शून्य न हो जाए, या किसी निश्चित ऑपरेशन के सफल समापन के लिए एक संकेत न मिल जाए। जब लूप स्थिति एक गैर-शून्य मान लौटाती है, जिसका अर्थ है त्रुटि, तो लूप बंद हो जाएगा।

यहां while लूप के संगठन का एक आरेख दिया गया है
जबकि कंडीशन चेक कमांड
करना
अन्य टीमें
हो गया

आइए इस तरह के लूप वाली एक उदाहरण स्क्रिप्ट पर नज़र डालें:

#!/bin/bash var1=5 जबकि [ $var1 -gt 0 ] प्रतिध्वनि करें $var1 var1=$[ $var1 - 1 ] हो गया
लूप के प्रवेश द्वार पर, यह जांचा जाता है कि वेरिएबल $var1 शून्य से अधिक है या नहीं। यदि ऐसा है, तो लूप की बॉडी निष्पादित होती है, जिसमें वेरिएबल के मान से एक घटा दिया जाता है। यह प्रत्येक पुनरावृत्ति में होता है, और हम संशोधित होने से पहले वेरिएबल के मान को कंसोल पर प्रिंट करते हैं। जैसे ही $var1 मान 0 पर पहुंचता है, लूप बंद हो जाता है।

थोड़ी देर के लूप का परिणाम

यदि आप $var1 वेरिएबल को संशोधित नहीं करते हैं, तो इससे स्क्रिप्ट अनंत लूप में समाप्त हो जाएगी।

स्थिर फंदा

आप लूप के मुख्य भाग में किसी भी कमांड का उपयोग कर सकते हैं, जिसमें अन्य लूप लॉन्च करना भी शामिल है। ऐसे निर्माणों को नेस्टेड लूप कहा जाता है:

#!/bin/bash for ((a = 1; a<= 3; a++)) do echo "Start $a:" for ((b = 1; b <= 3; b++)) do echo " Inner loop: $b" done done
नीचे बताया गया है कि यह स्क्रिप्ट क्या आउटपुट देगी। जैसा कि आप देख सकते हैं, पहले बाहरी लूप का पहला पुनरावृत्ति निष्पादित होता है, फिर आंतरिक लूप का तीन पुनरावृत्ति, इसके पूरा होने के बाद बाहरी लूप फिर से काम में आता है, फिर आंतरिक लूप फिर से काम में आता है।

स्थिर फंदा

फ़ाइल सामग्री संसाधित करना

अक्सर, नेस्टेड लूप्स का उपयोग फ़ाइलों को संसाधित करने के लिए किया जाता है। तो, बाहरी लूप फ़ाइल की पंक्तियों पर पुनरावृत्ति कर रहा है, और आंतरिक लूप पहले से ही प्रत्येक पंक्ति के साथ काम कर रहा है। उदाहरण के लिए, /etc/passwd फ़ाइल का प्रसंस्करण इस प्रकार दिखता है:

#!/bin/bash IFS=$"\n" $(cat /etc/passwd) में प्रविष्टि के लिए इको करें "$entry में मान -" IFS=: $entry में मान के लिए "$value" इको करें हो गया
इस स्क्रिप्ट में दो लूप हैं। पहला एक सीमांकक के रूप में न्यूलाइन वर्ण का उपयोग करके रेखाओं को पार करता है। आंतरिक वाला उन स्ट्रिंग्स को पार्स करने में व्यस्त है जिनके फ़ील्ड को कोलन द्वारा अलग किया गया है।

फ़ाइल डेटा प्रोसेसिंग

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

चक्र प्रबंधन

शायद, लूप में प्रवेश करने के बाद, आपको इसे रोकने की आवश्यकता होगी जब लूप वैरिएबल एक निश्चित मान तक पहुंच जाता है जो लूप को समाप्त करने के लिए प्रारंभ में निर्दिष्ट स्थिति के अनुरूप नहीं होता है। ऐसी स्थिति में क्या चक्र के सामान्य रूप से पूरा होने तक इंतजार करना जरूरी होगा? बिल्कुल नहीं, और ऐसे मामलों में निम्नलिखित दो कमांड काम आएंगे:
  • तोड़ना
  • जारी रखना

आदेश तोड़ो

यह कमांड आपको लूप के निष्पादन को बाधित करने की अनुमति देता है। इसका उपयोग for और while दोनों लूप के लिए किया जा सकता है:

#!/bin/bash for var1 in 1 2 3 4 5 6 7 8 9 10 यदि [ $var1 -eq 5 ] तो ब्रेक फाई इको "नंबर: $var1" हो गया
ऐसा लूप, सामान्य परिस्थितियों में, सूची से मूल्यों की पूरी सूची से गुजरेगा। हालाँकि, हमारे मामले में, इसका निष्पादन तब बाधित हो जाएगा जब $var1 वैरिएबल 5 के बराबर होगा।

फॉर लूप से जल्दी बाहर निकलना

यहाँ भी वही बात है, लेकिन थोड़ी देर के लूप के लिए:

#!/bin/bash var1=1 जबकि [ $var1 -lt 10 ] करें यदि [ $var1 -eq 5 ] तो ब्रेक फाई इको "Iteration: $var1" var1=$(($var1 + 1)) हो गया
ब्रेक कमांड, जब $var1 5 तक पहुंचता है, निष्पादित होता है, लूप को तोड़ देता है। कंसोल वही चीज़ प्रदर्शित करेगा जो पिछले उदाहरण में था।

आदेश जारी रखें

जब यह आदेश लूप के मुख्य भाग में आता है, तो वर्तमान पुनरावृत्ति जल्दी समाप्त हो जाती है और अगला पुनरावृत्ति शुरू हो जाती है, लूप से बाहर निकले बिना। आइए लूप में जारी रखें कमांड को देखें:

#!/bin/bash for ((var1 = 1; var1< 15; var1++)) do if [ $var1 -gt 5 ] && [ $var1 -lt 10 ] then continue fi echo "Iteration number: $var1" done
जब लूप के अंदर की स्थिति संतुष्ट हो जाती है, यानी, जब $var1 5 से अधिक और 10 से कम होता है, तो शेल जारी रखें कमांड निष्पादित करता है। इसके परिणामस्वरूप लूप के मुख्य भाग में शेष कमांड को छोड़ दिया जाता है और अगले पुनरावृत्ति पर चला जाता है।

लूप के लिए जारी रखें कमांड

प्रोसेसिंग आउटपुट एक लूप में चल रहा है

लूप से डेटा आउटपुट को या तो आउटपुट को रीडायरेक्ट करके या पाइपलाइन में पास करके संसाधित किया जा सकता है। यह किया गया कथन के बाद आउटपुट प्रोसेसिंग कमांड जोड़कर किया जाता है।

उदाहरण के लिए, स्क्रीन पर यह दिखाने के बजाय कि लूप में आउटपुट क्या है, आप यह सब एक फ़ाइल में लिख सकते हैं या इसे कहीं और पास कर सकते हैं:

#!/bin/bash for ((a = 1; a< 10; a++)) do echo "Number is $a" done >myfile.txt इको "समाप्त।"
शेल myfile.txt फ़ाइल बनाएगा और उस फ़ाइल के लिए स्टेटमेंट के आउटपुट को रीडायरेक्ट करेगा। आइए फ़ाइल खोलें और सुनिश्चित करें कि इसमें वही है जो हम अपेक्षा करते हैं।

लूप आउटपुट को फ़ाइल पर रीडायरेक्ट करें

उदाहरण: निष्पादन योग्य फ़ाइलें खोजें

आइए जो हमने पहले ही कवर किया है उसका उपयोग करें और कुछ उपयोगी लिखें। उदाहरण के लिए, यदि आपको यह पता लगाना है कि सिस्टम पर कौन सी निष्पादन योग्य फ़ाइलें उपलब्ध हैं, तो आप PATH पर्यावरण चर में दर्ज सभी फ़ोल्डरों को स्कैन कर सकते हैं। हमारे पास पहले से ही उपकरणों का पूरा भंडार है जिनकी हमें इसके लिए आवश्यकता है, हमें बस इन सभी को एक साथ रखने की आवश्यकता है:

#!/bin/bash IFS=: $PATH में फ़ोल्डर के लिए echo "$folder:" करें $folder/* में फ़ाइल के लिए यदि [ -x $file ] तो echo " $file" करें फाई हो गया
छोटी और सरल इस स्क्रिप्ट ने हमें PATH से फ़ोल्डरों में संग्रहीत निष्पादन योग्य फ़ाइलों की एक सूची प्राप्त करने की अनुमति दी।

PATH वेरिएबल से फ़ोल्डरों में निष्पादन योग्य फ़ाइलों की खोज करना

परिणाम

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

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

लूप प्रकारों में अंतर का संक्षिप्त विवरण:

के लिए - जब तक निष्पादित करने के लिए ऑब्जेक्ट हैं तब तक एक क्रिया निष्पादित करेगा (उदाहरण के लिए, stdin, एक फ़ाइल या एक फ़ंक्शन से एक स्ट्रीम पढ़ना);
जबकि - जब तक क्रिया करता है स्थितिक्या सच है;
जब तक - जब तक निष्पादित किया जाएगा स्थितिसच नहीं होगा, यानी फिलहाल यह झूठ है.

पाश के लिए

आइए स्क्रिप्ट के इस संस्करण पर एक लूप के साथ विचार करें:

$ cat लूप.sh #!/bin/bash `ls -1` में वेरिएबल के लिए इको "$वेरिएबल" पूरा करें

वाक्यविन्यास बहुत सरल है और उदाहरण में स्पष्ट रूप से दिखाया गया है:

(लूप शुरू करें) वेरिएबल के लिए (एक वेरिएबल घोषित करें जिस पर हम कार्रवाई करेंगे) (लूप में एक प्रवाह भेजें) `ls -1` (कमांड को निष्पादित किया जाएगा और $variable वेरिएबल को पास किया जाएगा)। करो और किया गया लूप का "बॉडी" है, जिसके भीतर प्राप्त डेटा पर मुख्य क्रियाएं की जाएंगी, और इको "$variable" लूप द्वारा की गई वास्तविक क्रिया है।

अब उदाहरण को थोड़ा बदलते हैं, और कमांड को स्पष्ट रूप से निर्दिष्ट करने के बजाय, हम दूसरे वेरिएबल का उपयोग करेंगे:

$ cat लूप.sh #!/bin/bash ls=`ls -1` $ls में वेरिएबल के लिए "$variable" इको करें

अब ls -1 कमांड को एक अलग वेरिएबल में पास किया जाता है, जो आपको लूप के साथ अधिक लचीले ढंग से काम करने की अनुमति देता है। लूप में एक वेरिएबल के बजाय, आप एक फ़ंक्शन का भी उपयोग कर सकते हैं:

$ cat loop.sh #!/bin/bash lsl () ( ls -1 ) `lsl` में वेरिएबल के लिए इको "$variable" करें

फॉर लूप की मुख्य शर्त यह है कि इसे तब तक निष्पादित किया जाएगा जब तक इसमें पारित कमांड में कार्रवाई के लिए ऑब्जेक्ट शामिल हैं। उपरोक्त उदाहरण के आधार पर - जब तक ls -1 में प्रदर्शित करने के लिए फ़ाइलें हैं - लूप उन्हें एक वेरिएबल में भेज देगा और "लूप बॉडी" निष्पादित करेगा। जैसे ही निर्देशिका में फ़ाइलों की सूची समाप्त होगी, लूप अपना निष्पादन पूरा कर लेगा।

आइए उदाहरण को थोड़ा और जटिल बनाएं।

निर्देशिका में फ़ाइलों की एक सूची है:

$ ls -1 फ़ाइल1 फ़ाइल2 फ़ाइल3 फ़ाइल4 फ़ाइल5 लूप.श नोफ़ाइल1 नोफ़ाइल2 नोफ़ाइल3 नोफ़ाइल4 नोफ़ाइल5

हमें उनमें से केवल उन्हीं का चयन करना है जिनके पास "शब्द" नहीं है। नहीं«:

$ cat loop.sh #!/bin/bash lsl=`ls -1` $lsl में वेरिएबल के लिए echo "$variable" करें | grep -v "नहीं" हो गया $ ./loop.sh फ़ाइल1 फ़ाइल2 फ़ाइल3 फ़ाइल4 फ़ाइल5 लूप.sh

आप लूप में सशर्त अभिव्यक्तियों का भी उपयोग कर सकते हैं ( सशर्त अभिव्यक्तियाँ) […] स्थितियों की जांच करने के लिए और यदि स्थिति ट्रिगर होती है तो लूप को बाधित करने के लिए ब्रेक स्टेटमेंट।

इस उदाहरण पर विचार करें:

$ cat loop.sh #!/bin/bash lsl=`ls -1` $lsl में वेरिएबल के लिए यदि [ $variable != "loop.sh" ] करें तो echo "$variable" | grep -v "नहीं" अन्यथा ब्रेक फाई हो गया

लूप तब तक जारी रहेगा जब तक कि लूप.श फ़ाइल सामने न आ जाए। जैसे ही लूप का निष्पादन इस फ़ाइल तक पहुँचता है, लूप ब्रेक कमांड द्वारा बाधित हो जाएगा:

$ ./loop.sh फ़ाइल1 फ़ाइल2 फ़ाइल3 फ़ाइल4 फ़ाइल5

एक अन्य उदाहरण लूप के मुख्य भाग को क्रियान्वित करने से ठीक पहले अंकगणितीय संक्रियाओं का उपयोग है:

$ कैट लूप.श #!/बिन/बैश फॉर ((काउंट=1; काउंट<11; count++)) do echo "$count" done

यहां हमने तीन नियंत्रण आदेश निर्धारित किए हैं - गिनती = 1, एक नियंत्रित स्थिति - जबकि गिनती 11 से कम है, और निष्पादित करने के लिए एक आदेश - गिनती +1:

जबकि और जब तक लूप

एक सरल उदाहरण जो स्पष्ट रूप से दर्शाता है कि while लूप कैसे काम करता है:

$ cat लूप.sh #!/bin/bash गिनती=0 जबकि [ $गिनती -lt 10 ] करो ((गिनती++)) प्रतिध्वनि $गिनती हो गई

हम $count वैरिएबल को शून्य पर सेट करते हैं, और फिर while लूप को इस शर्त के साथ चलाते हैं "जबकि $count दस से कम है, लूप निष्पादित करें।" लूप के मुख्य भाग में हम निष्पादित करते हैं पोस्टफ़िक्स वृद्धि$count वैरिएबल को +1 करें और परिणाम stdout पर मुद्रित किया जाता है।

निष्पादन परिणाम:

$ ./लूप.श 1 2 3 4 5 6 7 8 9 10

जैसे ही $count वेरिएबल का मान 10 हो गया, लूप बंद हो गया।

"अनंत" लूप का एक अच्छा उदाहरण जो दर्शाता है कि while कैसे काम करता है:

$ कैट लूप.श #!/बिन/बैश काउंट=10 जबकि [1 = 1 ] करें ((गिनती++)) इको $काउंट हो गया $ ./लूप.श ... 5378 5379 5380 5381 5382 5383 ^सी

जब तक लूप समान रूप से काम करता है, लेकिन विपरीत दिशा में:

$ cat loop.sh #!/bin/bash count=0 जब तक [ $count -gt 10 ] do ((count++)) echo $count हो गया

यहां हमने एक समान शर्त निर्धारित की है, लेकिन "जबकि चर 10 से कम है" के बजाय, हम "जब तक चर 10 से अधिक नहीं हो जाता" निर्दिष्ट करते हैं। निष्पादन परिणाम:

$ ./loop.sh 1 2 3 4 5 6 7 8 9 10 11

यदि "अंतहीन लूप" का उपरोक्त उदाहरण तब तक निष्पादित किया जाता है, तो यह while के विपरीत, कुछ भी आउटपुट नहीं करेगा:

$ कैट लूप.श #!/बिन/बैश काउंट=10 जब तक [1 = 1 ] न करें ((काउंट++)) इको $काउंट हो गया $ ./लूप.श $

क्योंकि " स्थिति"मौलिक रूप से" सत्य"-लूप का मुख्य भाग निष्पादित नहीं किया जाएगा।

फ़ॉर लूप की तरह ही, आप while और जब तक फ़ंक्शंस का उपयोग कर सकते हैं। उदाहरण के लिए, वास्तविक जीवन की स्क्रिप्ट से एक लूप जो सर्वर स्थिति की जाँच करता है बिल्ला(पीआईडी ​​सिस्टम से लिया गया है एसएलईएस, अन्य प्रणालियों में भिन्न हो सकता है), थोड़ा सरलीकृत संस्करण:

$ cat loop.sh #!/bin/bash check_tomcat_status () ( RUN=`ps aux | grep tomcat | grep -v grep | grep java | awk "(print $2)"` ) जबकि check_tomcat_status ऐसा करें यदि [ -n "$ RUN" ] फिर प्रिंट करें "चेतावनी: टॉमकैट अभी भी PID $RUN के साथ चल रहा है।" अन्यथा प्रिंटफ "टॉमकैट रुक गया, आगे बढ़ रहा है...एनएन" ब्रेक फाई हो गया

निष्पादन परिणाम:

$ ./loop.sh चेतावनी: टॉमकैट अभी भी पीआईडी ​​14435 26548 के साथ चल रहा है। चेतावनी: टॉमकैट अभी भी पीआईडी ​​14435 26548 के साथ चल रहा है। चेतावनी: टॉमकैट अभी भी पीआईडी ​​14435 26548 के साथ चल रहा है। चेतावनी: टॉमकैट अभी भी पीआईडी ​​14435 26548 के साथ चल रहा है। चेतावनी: टॉमकैट अभी भी पीआईडी ​​14435 26548 के साथ चल रहा है। पीआईडी ​​14435 26548 के साथ चल रहा है। चेतावनी: टॉमकैट अभी भी पीआईडी ​​14435 26548 के साथ चल रहा है। चेतावनी: टॉमकैट अभी भी पीआईडी ​​14435 26548 के साथ चल रहा है। चेतावनी: टॉमकैट अभी भी पीआईडी ​​14435 के साथ चल रहा है।

पूर्ण संस्करण:

Check_tomcat_status () ( RUN=`ps aux | grep tomcat | grep -v grep | grep java | awk "(प्रिंट $2)"` ) जबकि check_tomcat_status; यदि [ -n "$RUN" ] करें तो प्रिंटफ करें "चेतावनी: टॉमकैट अभी भी PID $RUN के साथ चल रहा है। इसे रोकें? " उत्तर "टॉमकैट को रोक रहा है..." "इंस्टॉलेशन आगे बढ़ रहा है..." && $CATALINA_HOME/bin/shutdown . श 2&>1 /dev/null || नींद तोड़ो 2 यदि [ -n "$RUN" ] तो प्रिंटफ "टॉमकैट अभी भी चल रहा है। इसे मार डालो? " उत्तर "टॉमकैट को मार रहा है..." "इंस्टॉलेशन आगे बढ़ रहा है...n" && $RUN को मार डालो || ब्रेक स्लीप 2 फाई अन्यथा प्रिंटफ "टॉमकैट रुक गया, आगे बढ़ रहा है...एनएन" ब्रेक फाई हो गया

उत्तर फ़ंक्शन का वर्णन आलेख में किया गया था, लेकिन यहां थोड़ा बेहतर संस्करण उपयोग किया गया है:

उत्तर () (प्रतिक्रिया पढ़ते समय; इको केस $रिस्पांस इन |) प्रिंटफ "$1एन" रिटर्न 0 ब्रेक ;; |) printf "$2n" रिटर्न 1 ब्रेक ;; *) प्रिंटफ "कृपया, Y(हाँ) या N(नहीं) दर्ज करें!" esac हो गया)

यहां while और जब तक - दोनों का उपयोग करना संभव था, लेकिन for लूप का नहीं, क्योंकि for ने एक बार काम किया होगा (PID प्राप्त किया और समाप्त हो गया)।

किसी भी प्रोग्राम या स्क्रिप्ट को लिखते समय लूप्स एक अत्यंत सुविधाजनक चीज़ है, बल्कि आवश्यक भी है। वे हमें कोड के एक निश्चित अनुभाग को निर्दिष्ट संख्या में निष्पादित करने की अनुमति देते हैं। स्वाभाविक रूप से, बैश में कई प्रकार के लूप होते हैं। हम चक्रों का वर्णन करेंगे में, के लिए, जबकि, जब तक. हालाँकि for in और for को एक ही कथन के अलग-अलग वाक्य-विन्यास माने जाते हैं, मेरी राय में वे while से तब तक की तुलना में एक-दूसरे से अधिक भिन्न हैं।

इन के लिए काउंटर के साथ लूप:

चक्र में लिएयह एक काउंटर वाला लूप है. लूप के मुख्य भाग में स्थित कोड के ब्लॉक को उतनी बार दोहराया जाता है जितनी बार इन ऑपरेटर की सूची में निहित मान होते हैं, और प्रत्येक पुनरावृत्ति के साथ, काउंटर वैरिएबल (यहां इसे var कहा जाता है, लेकिन निश्चित रूप से) आप इसे जो चाहें कह सकते हैं) में सूची के अगले तत्व का मूल्य है।
यदि कीवर्ड do शब्द के समान पंक्ति पर है, तो तर्कों की सूची के बाद (do से पहले) आपको अर्धविराम लगाना होगा।
प्रत्येक तत्व<список>इसमें कई तर्क हो सकते हैं. पैरामीटरों के समूहों को संसाधित करते समय यह उपयोगी होता है। इस मामले में, प्रत्येक तर्क को जबरदस्ती पार्स करने के लिए<списке>, आपको सेट निर्देश का उपयोग करना होगा
आप फॉर लूप में एक वेरिएबल को एक सूची के रूप में उपयोग कर सकते हैं।
में<списке>फॉर लूप फ़ाइल नामों का उपयोग कर सकता है, जिसमें बदले में वाइल्डकार्ड वर्ण हो सकते हैं। बड़ी संख्या में फ़ाइलों के साथ काम करते समय यह बहुत उपयोगी हो सकता है।
अगर<список>लूप के लिए निर्दिष्ट नहीं है, तो वेरिएबल $@ का उपयोग इसके रूप में किया जाता है - कमांड लाइन तर्कों की एक सूची।
तर्कों की सूची बनाते समय, आप लूप में कमांड प्रतिस्थापन का उपयोग कर सकते हैं।
लूप के आउटपुट को stdout से किसी फ़ाइल या कहीं और रीडायरेक्ट किया जा सकता है (आप I/O रीडायरेक्शन को देखकर इसके बारे में अधिक जान सकते हैं)।

वाक्य - विन्यास:
var in के लिए<список>
करना
<выполняемые команды>
हो गया

उदाहरण:
नाम1 नाम2 नाम3 नाम4 में नामों के लिए
करना
प्रतिध्वनि $नाम
हो गया

लूप ऑपरेटर के लिएलिखने का एक और तरीका है - सी भाषा में ऑपरेटर के सिंटैक्स के समान। इस मामले में, काउंटरों को प्रारंभ करते समय, चर या एक चर के प्रारंभिक मान सेट किए जाते हैं और लूप के प्रत्येक पास के बाद स्थिति जाँच की जाती है, यदि जाँच सही आती है, तो लूप का अगला पास शुरू होता है। ब्लॉक में<приращение счётчиков>हमारे वैरिएबल काउंटरों का मान आवश्यक रूप से बदलना चाहिए (जरूरी नहीं कि ऊपर की ओर) ताकि स्थिति की जाँच करते समय, देर-सबेर हमें मान गलत मिले, अन्यथा लूप कभी समाप्त नहीं होगा। यदि किसी ऑपरेशन को निर्दिष्ट संख्या में दोहराने की आवश्यकता होती है तो यह एक बहुत ही सुविधाजनक और सबसे महत्वपूर्ण रूप से परिचित विकल्प है।

समान वाक्यविन्यास के साथ:
के लिए ((<инициализация счётчиков>; <проверка условия>; <приращение счётчиков>))
करना
<выполняемые команды>
हो गया

उदाहरण:
((var=1; var<= LIMIT ; var++))
करना
प्रतिध्वनि $var
हो गया

घुमाव के दौरान:

यह एक काफी सरल निर्माण है जो ऑपरेटर के पीछे की स्थिति की जांच करता है जबकिऔर यदि यह शर्त सत्य है, तो यह करो और किया शब्दों के बीच स्थित आदेशों के ब्लॉक को निष्पादित करता है और फिर शर्त की जांच करने के लिए आगे बढ़ता है। यदि चेक गलत लौटाता है, तो चक्र समाप्त हो जाता है और निम्नलिखित आदेश निष्पादित होने लगते हैं: हो गया. यह सुनिश्चित करना अति आवश्यक है<проверка условия>लूप में चल रहे कोड पर निर्भर; अन्यथा, यदि चेक का परिणाम नहीं बदलता है, तो आपको एक अनंत लूप मिलेगा।
थोड़ी देर के लूप के लिए मानक इनपुट डिवाइस को रीडायरेक्शन कमांड का उपयोग करके फ़ाइल पर रीडायरेक्ट किया जा सकता है< в конце цикла.

वाक्य - विन्यास:
जबकि<Проверка условия>
करना
<Блок команд, обязательно меняющий переменные влияющие на проверку условия>
हो गया

उदाहरण:
जबकि [ $var0 -eq 100 ]
करना
प्रतिध्वनि $var
var++
हो गया

ऑपरेटर जबकिकई शर्तें हो सकती हैं. लेकिन उनमें से केवल अंतिम ही चक्र जारी रखने की संभावना निर्धारित करता है। इस स्थिति में, लूप ऑपरेटर का सिंटैक्स सामान्य से भिन्न होगा।
वाक्य - विन्यास(मैं एक बार फिर दोहराता हूं कि केवल अंतिम स्थिति ही लूप के निष्पादन को प्रभावित करती है) :
जबकि
<условие1>
<условие2>

<условиеN>
करना
<выполняемые команды - тело цикла>
हो गया

लूप तक:

ऑपरेटर जब तकयह बहुत हद तक while के समान है, यह स्थिति का मूल्यांकन भी करता है, लेकिन यदि गणना का परिणाम गलत है तो लूप के मुख्य भाग को निष्पादित करता है। यह असामान्य लग सकता है, लेकिन जब तक लूप के पहले पास से पहले की स्थिति का मूल्यांकन नहीं किया जाता, जैसे कि while, और उसके बाद नहीं। फॉर/इन लूप्स की तरह, do कीवर्ड को लूप घोषणा के समान लाइन पर रखते समय, आपको एक ";" अक्षर डालना होगा। करने से पहले.
पिछले मामले की तरह, यह याद रखना महत्वपूर्ण है कि स्थिति लूप बॉडी में संचालन पर निर्भर होनी चाहिए, अन्यथा हमारी स्क्रिप्ट कभी पूरी नहीं होगी।

वाक्य - विन्यास:
जब तक<Проверка условия>
करना
<Блок команд, обязательно меняющий переменные влияющие на проверку условия>
हो गया

उदाहरण:
जब तक [ $var0 -gt 100] # पुनरावृत्ति की शुरुआत में स्थिति की जाँच की जाती है।
करना
प्रतिध्वनि $var
वर--
हो गया

अभी के लिए शायद इतना ही काफी है. :)

  • पीछे
  • आगे

नए लेख:

  • Windows 7/8/2008/2012 में नेटवर्क खोज चालू नहीं होती है
  • त्रुटि: यह एप्लिकेशन प्रारंभ होने में विफल रहा क्योंकि यह Qt प्लेटफ़ॉर्म प्लगइन "विंडोज़" ढूंढ या लोड नहीं कर सका।
  • 1C 8.3 सर्वर पर rphost.exe वर्कर प्रक्रियाओं का स्वचालित पुनरारंभ कॉन्फ़िगर करना
  • MS SQL 2008/20012 में लेनदेन लॉग (.ldf) का आकार कैसे कम करें

    MS SQL, किसी भी अच्छे औद्योगिक DBMS की तरह, डेटाबेस के साथ, लेनदेन लॉग रखता है जो आपको स्थिति को वापस रोल करने की अनुमति देता है...

0 मीरां बाला-कुमारन

मैं वास्तव में यह समझने की कोशिश कर रहा हूं कि यह while लूप कभी समाप्त क्यों नहीं होता है, जब लूप शुरू होता है तो मेरा LOC वैरिएबल Testing/ पर सेट हो जाता है, जो कि इस प्रोग्राम का परीक्षण करने के लिए बनाई गई निर्देशिका है, जिसमें निम्नलिखित लेआउट है:

मैं चाहता हूं कि सभी निर्देशिकाओं में "गिनती" फ़ंक्शन लागू होने के बाद लूप समाप्त हो जाए।
मैंने यही प्रयास किया;

मैंने गिनती फ़ंक्शन की जांच की और यह अनंत लूप नहीं बनाता है

मैंने एल्गोरिदम को मैन्युअल रूप से चलाने का प्रयास किया

PARSE=1 LOC=$LOC/ गिनती उपलब्धDIR=$(ls $LOC -AFl | sed "1 d" | grep "/$" | awk "( print $9 )") जबकि [ $PARSE = "1" ] यदि करें [[ $(AVAILABLEDIR[@]) == "" ]]; फिर PARSE=0 fi DIRBASE=$LOC for a in $(AVAILABLEDIR[@]); $(LOCLIST[@]) में a के लिए LOC='$(DIRBASE)$(a)' LOCLIST='$LOCLIST $LOC' गिनती करें; do TMPAVAILABLEDIR=$(ls $a -AFl | sed "1 d" | grep "/$" | awk "( print $9 )") PREPEND=$a यदि [[ $(TMPAVAILABLEDIR[@]) == "" ] ]; फिर $(TMPAVAILABLEDIR[@]) में a के लिए फाई जारी रखें; TMPAVAILABLEDIR2='$TMPAVAILABLEDIR2 $(PREPEND[@])$(a)' हो गया NEWAVAILABLEDIR='$NEWAVAILABLEDIR $TMPAVAILABLEDIR2' हो गया AVAILABLEDIR=$NEWAAVAILABLEDIR NEWAVAILABLEDIR='' LOC='' हो गया

मैं वास्तव में संघर्ष कर रहा हूं और किसी भी इनपुट की बहुत सराहना की जाएगी, मैं पिछले दो घंटों से इसका पता लगाने की कोशिश कर रहा हूं।

अनंत-लूप को बैश करें

4 उत्तर

आपको स्क्रिप्ट को -x तर्क के साथ चलाने या पहली पंक्ति पर लिखने का प्रयास करना चाहिए:

#!/बिन/बैश -x

फिर वह तुम्हें वह सब कुछ बताता है जो वह करता है।

इस मामले में, आपको दो त्रुटियाँ दिखाई दे सकती हैं:

    आप कभी भी TMPAVAILABLEDIR2 को दोबारा लोड नहीं करेंगे

    आप नियमित फ़ाइलों पर भी ls करते हैं।

यदि आपको वास्तव में प्रत्यावर्तन से बचना है, तो इसे पूरी तरह से बिना प्रत्यावर्तन के आज़माएँ:

#!/बिन/बैश काउंट() (इको काउंटिंग "$1") todo=(टेस्टिंग) जबकि टेस्ट $(#todo[@]) != 0 doit=("$(todo[@])") todo= () "$(doit[@])" में dir के लिए "$dir"/* में प्रविष्टि के लिए करें # यदि dir खाली है, तो यह "*" नाम की एक प्रविष्टि दिखाता है do test -e "$entry" || जारी रखें # खाली डीआईआर की प्रविष्टि "*" को छोड़ें गिनती "$entry" test -d "$entry" || जारी रखें do+=("$entry") हो गया, हो गया

हालाँकि, कृपया मुझे बताएं कि आप रिकर्सन का उपयोग क्यों नहीं कर सकते? क्या यह किसी प्रकार की एलर्जी है? प्रतिज्ञा? क्या आप जहां रहते हैं वहां पुनरावर्ती सॉफ़्टवेयर के विरुद्ध कोई स्थानीय कानून हैं?

आपने लिखा है कि आप सभी कटों पर "गिनती" करना चाहते हैं। खोज विकल्प देखें:

$LOC -प्रकार d | खोजें जबकि डीआईआर पढ़ें; cd $LOC cd $(dir) गिनती पूरी हो गई

या छोटा (जब आपका फ़ंक्शन काउंटर निर्देशिका को पैरामीटर 1 के रूप में लेता है)

$LOC -प्रकार d | खोजें xargs गिनती

अब मैं देख रहा हूं कि आप ढूंढें या ls -R (पुनरावर्ती फ़ंक्शन) का उपयोग नहीं करना चाहते हैं। फिर आपको अपना स्वयं का पुनरावर्ती कार्य बनाना चाहिए

फ़ंक्शन parseDir ( ls -d */ $1 | dir पढ़ते समय; गिनें कि parseDir $1/$dir हो गया )

मुझे नहीं पता कि यह काम करेगा या नहीं, लेकिन यह एक दिलचस्प सवाल है जिसके बारे में मैं सोचना बंद नहीं कर सका। आपको कामयाबी मिले

जबकि सच है; "$(echo *)" में शब्द के लिए करें; यदि [[ -d "$word" ]] करें; फिर d[$((i++))]='$PWD'/'$word' elif [[ -f '$word' ]] ;फिर f[$((j++))]='$PWD'/'$ शब्द" फाई हो गया [[ $k -gt $i ]] && cd .. cd "$d[$((k++))]" || ब्रेक हो गया



मित्रों को बताओ