Computer >> कंप्यूटर >  >> प्रोग्रामिंग >> बाश प्रोग्रामिंग

बैश के साथ प्रोग्राम कैसे करें:लूप्स

बैश एक शक्तिशाली प्रोग्रामिंग भाषा है, जिसे कमांड लाइन और शेल स्क्रिप्ट में उपयोग के लिए पूरी तरह से डिज़ाइन किया गया है। मेरे तीन-खंड वाले लिनक्स स्व-अध्ययन पाठ्यक्रम पर आधारित यह तीन-भाग श्रृंखला, कमांड-लाइन इंटरफ़ेस (CLI) पर प्रोग्रामिंग भाषा के रूप में बैश का उपयोग करने की खोज करती है।

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

लूप्स

मेरे द्वारा उपयोग की जाने वाली प्रत्येक प्रोग्रामिंग भाषा में कम से कम दो प्रकार की लूप संरचनाएं होती हैं जो दोहराए जाने वाले कार्यों को करने के लिए विभिन्न क्षमताएं प्रदान करती हैं। मैं लूप के लिए अक्सर उपयोग करता हूं लेकिन मुझे लूप उपयोगी होने तक और समय भी लगता है।

लूप के लिए

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

के लिए . के बैश संस्करण की मूल संरचना आदेश सरल है:

for Var in list1 ; do list2 ; done

इसका अनुवाद इस प्रकार है: "सूची 1 में प्रत्येक मान के लिए, $Var . सेट करें उस मान के लिए और फिर उस मान का उपयोग करके सूची 2 में प्रोग्राम स्टेटमेंट निष्पादित करें; जब सूची 1 में सभी मानों का उपयोग किया गया है, तो यह समाप्त हो गया है, इसलिए लूप से बाहर निकलें।" सूची 1 में मान मानों की एक सरल, स्पष्ट स्ट्रिंग हो सकते हैं, या वे कमांड प्रतिस्थापन का परिणाम हो सकते हैं (दूसरे में वर्णित) श्रृंखला में लेख)। मैं इस निर्माण का अक्सर उपयोग करता हूं।

इसे आज़माने के लिए, सुनिश्चित करें कि ~/testdir अभी भी वर्तमान कार्यशील निर्देशिका (पीडब्ल्यूडी) है। निर्देशिका को साफ करें, फिर के लिए . का एक छोटा सा उदाहरण देखें मूल्यों की एक स्पष्ट सूची के साथ शुरू होने वाला लूप। यह सूची अक्षरांकीय मानों का मिश्रण है—लेकिन यह न भूलें कि सभी चर तार हैं और उन्हें इस तरह माना जा सकता है।

[student@studentvm1 testdir]$ rm *
[student@studentvm1 testdir]$ for I in a b c d 1 2 3 4 ; do echo $I ; done
a
b
c
d
1
2
3
4

यहाँ एक अधिक सार्थक चर नाम के साथ थोड़ा अधिक उपयोगी संस्करण है:

[student@studentvm1 testdir]$ for Dept in "Human Resources" Sales Finance "Information Technology" Engineering Administration Research ; do echo "Department $Dept" ; done 
Department Human Resources
Department Sales
Department Finance
Department Information Technology
Department Engineering
Department Administration
Department Research

कुछ निर्देशिकाएं बनाएं (और ऐसा करते समय कुछ प्रगति जानकारी दिखाएं):

[student@studentvm1 testdir]$ for Dept in "Human Resources" Sales Finance "Information Technology" Engineering Administration Research ; do echo "Working on Department $Dept" ; mkdir "$Dept"  ; done 
Working on Department Human Resources
Working on Department Sales
Working on Department Finance
Working on Department Information Technology
Working on Department Engineering
Working on Department Administration
Working on Department Research
[student@studentvm1 testdir]$ ll
total 28
drwxrwxr-x 2 student student 4096 Apr  8 15:45  Administration
drwxrwxr-x 2 student student 4096 Apr  8 15:45  Engineering
drwxrwxr-x 2 student student 4096 Apr  8 15:45  Finance
drwxrwxr-x 2 student student 4096 Apr  8 15:45 'Human Resources'
drwxrwxr-x 2 student student 4096 Apr  8 15:45 'Information Technology'
drwxrwxr-x 2 student student 4096 Apr  8 15:45  Research
drwxrwxr-x 2 student student 4096 Apr  8 15:45  Sales

$विभाग चर mkdir . में उद्धरणों में संलग्न होना चाहिए बयान; अन्यथा, दो-भाग वाले विभाग के नाम (जैसे "सूचना प्रौद्योगिकी") को दो अलग-अलग विभागों के रूप में माना जाएगा। यह मेरे द्वारा अनुसरण किए जाने वाले सर्वोत्तम अभ्यास पर प्रकाश डालता है:सभी फ़ाइल और निर्देशिका नाम एक ही शब्द होना चाहिए। हालांकि अधिकांश आधुनिक ऑपरेटिंग सिस्टम नामों में रिक्त स्थान से निपट सकते हैं, यह सुनिश्चित करने के लिए sysadmins के लिए अतिरिक्त काम लेता है कि उन विशेष मामलों को स्क्रिप्ट और सीएलआई कार्यक्रमों में माना जाता है। (उन्हें लगभग निश्चित रूप से माना जाना चाहिए, भले ही वे परेशान हों क्योंकि आप कभी नहीं जानते कि आपके पास कौन सी फाइलें होंगी।)

तो, ~/testdir . में सब कुछ हटा दें —फिर से—और इसे एक बार और करें:

[student@studentvm1 testdir]$ rm -rf * ; ll
total 0
[student@studentvm1 testdir]$ for Dept in Human-Resources Sales Finance Information-Technology Engineering Administration Research ; do echo "Working on Department $Dept" ; mkdir "$Dept"  ; done
Working on Department Human-Resources
Working on Department Sales
Working on Department Finance
Working on Department Information-Technology
Working on Department Engineering
Working on Department Administration
Working on Department Research
[student@studentvm1 testdir]$ ll
total 28
drwxrwxr-x 2 student student 4096 Apr  8 15:52 Administration
drwxrwxr-x 2 student student 4096 Apr  8 15:52 Engineering
drwxrwxr-x 2 student student 4096 Apr  8 15:52 Finance
drwxrwxr-x 2 student student 4096 Apr  8 15:52 Human-Resources
drwxrwxr-x 2 student student 4096 Apr  8 15:52 Information-Technology
drwxrwxr-x 2 student student 4096 Apr  8 15:52 Research
drwxrwxr-x 2 student student 4096 Apr  8 15:52 Sales

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

आप इससे कैसे संपर्क करेंगे? यहाँ एक तरीका है, इस ज्ञान से शुरू करते हुए कि rpm –qa कमांड एक आरपीएम का पूरा विवरण प्रदान करता है, जिसमें पीएचबी को दो आइटम शामिल हैं:सॉफ्टवेयर का नाम और एक संक्षिप्त सारांश।

अंतिम परिणाम तक एक बार में एक कदम बढ़ाएं। सबसे पहले, सभी RPM को सूचीबद्ध करें:

[student@studentvm1 testdir]$ rpm -qa 
perl-HTTP-Message-6.18-3.fc29.noarch
perl-IO-1.39-427.fc29.x86_64
perl-Math-Complex-1.59-429.fc29.noarch
lua-5.3.5-2.fc29.x86_64
java-11-openjdk-headless-11.0.ea.28-2.fc29.x86_64
util-linux-2.32.1-1.fc29.x86_64
libreport-fedora-2.9.7-1.fc29.x86_64
rpcbind-1.2.5-0.fc29.x86_64
libsss_sudo-2.0.0-5.fc29.x86_64
libfontenc-1.1.3-9.fc29.x86_64
<snip>

क्रमबद्ध करें जोड़ें और uniq सूची को क्रमबद्ध करने और अद्वितीय को प्रिंट करने के लिए आदेश (चूंकि यह संभव है कि समान नाम वाले कुछ RPM स्थापित किए गए हों):

[student@studentvm1 testdir]$ rpm -qa | sort | uniq
a2ps-4.14-39.fc29.x86_64
aajohan-comfortaa-fonts-3.001-3.fc29.noarch
abattis-cantarell-fonts-0.111-1.fc29.noarch
abiword-3.0.2-13.fc29.x86_64
abrt-2.11.0-1.fc29.x86_64
abrt-addon-ccpp-2.11.0-1.fc29.x86_64
abrt-addon-coredump-helper-2.11.0-1.fc29.x86_64
abrt-addon-kerneloops-2.11.0-1.fc29.x86_64
abrt-addon-pstoreoops-2.11.0-1.fc29.x86_64
abrt-addon-vmcore-2.11.0-1.fc29.x86_64
<snip>

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

[student@studentvm1 testdir]$ for RPM in `rpm -qa | sort | uniq` ; do rpm -qi $RPM ; done

यह कोड आपकी अपेक्षा से अधिक डेटा उत्पन्न करता है। ध्यान दें कि लूप पूरा हो गया है। अगला कदम केवल PHB द्वारा अनुरोधित जानकारी को निकालना है। तो, एक egrep . जोड़ें कमांड, जिसका उपयोग ^नाम . को चुनने के लिए किया जाता है या ^सारांश . कैरेट (^ ) लाइन की शुरुआत निर्दिष्ट करता है; इस प्रकार, पंक्ति की शुरुआत में नाम या सारांश वाली कोई भी पंक्ति प्रदर्शित होती है।

RPM के लिए
[student@studentvm1 testdir]$ for RPM in `rpm -qa | sort | uniq` ; do rpm -qi $RPM ; done | egrep -i "^Name|^Summary"
Name        : a2ps
Summary     : Converts text and other types of files to PostScript
Name        : aajohan-comfortaa-fonts
Summary     : Modern style true type font
Name        : abattis-cantarell-fonts
Summary     : Humanist sans serif font
Name        : abiword
Summary     : Word processing program
Name        : abrt
Summary     : Automatic bug detection and reporting tool
<snip>

आप grep try को आजमा सकते हैं egrep . के बजाय उपरोक्त आदेश में, लेकिन यह काम नहीं करेगा। आप इस कमांड के आउटपुट को कम . के माध्यम से भी पाइप कर सकते हैं परिणामों का पता लगाने के लिए फ़िल्टर करें। अंतिम कमांड अनुक्रम इस तरह दिखता है:

[student@studentvm1 testdir]$ for RPM in `rpm -qa | sort | uniq` ; do rpm -qi $RPM ; done | egrep -i "^Name|^Summary" > RPM-summary.txt

यह कमांड-लाइन प्रोग्राम पाइपलाइनों, पुनर्निर्देशन और के लिए . का उपयोग करता है लूप - सभी एक ही लाइन पर। यह आपके छोटे से सीएलआई प्रोग्राम के आउटपुट को एक फाइल पर रीडायरेक्ट करता है जिसका उपयोग ईमेल में या अन्य उद्देश्यों के लिए इनपुट के रूप में किया जा सकता है।

कार्यक्रम को एक बार में एक कदम बनाने की यह प्रक्रिया आपको प्रत्येक चरण के परिणाम देखने और यह सुनिश्चित करने की अनुमति देती है कि यह आपकी अपेक्षा के अनुरूप काम कर रहा है और वांछित परिणाम प्रदान करता है।

इस अभ्यास से, PHB को 1,900 से अधिक अलग RPM पैकेजों की एक सूची प्राप्त हुई। मुझे गंभीरता से संदेह है कि किसी ने उस सूची को पढ़ा है। लेकिन मैंने उन्हें वही दिया जो उन्होंने माँगा, और मैंने उनसे इसके बारे में एक और शब्द कभी नहीं सुना।

अन्य लूप

बैश में दो और प्रकार की लूप संरचनाएं उपलब्ध हैं:जबकि और तक संरचनाएँ, जो वाक्य रचना और कार्य दोनों में एक दूसरे से बहुत मिलती-जुलती हैं। इन लूप संरचनाओं का मूल सिंटैक्स सरल है:

while [ expression ] ; do list ; done

और

until [ expression ] ; do list ; done

पहले का तर्क पढ़ता है:"जबकि अभिव्यक्ति सत्य के रूप में मूल्यांकन करती है, प्रोग्राम स्टेटमेंट की सूची निष्पादित करें। जब अभिव्यक्ति झूठी के रूप में मूल्यांकन करती है, तो लूप से बाहर निकलें।" और दूसरा:"जब तक अभिव्यक्ति सत्य के रूप में मूल्यांकन नहीं करती है, प्रोग्राम स्टेटमेंट की सूची निष्पादित करें। जब अभिव्यक्ति सत्य के रूप में मूल्यांकन करती है, तो लूप से बाहर निकलें।"

लूप के दौरान

जबकि लूप का उपयोग प्रोग्राम स्टेटमेंट की एक श्रृंखला को निष्पादित करने के लिए किया जाता है (जब तक) तार्किक अभिव्यक्ति सत्य के रूप में मूल्यांकन करती है। आपका पीडब्ल्यूडी अभी भी ~/testdir होना चाहिए ।

जबकि . का सबसे सरल रूप लूप वह है जो हमेशा के लिए चलता है। निम्न प्रपत्र हमेशा "सत्य" रिटर्न कोड उत्पन्न करने के लिए सत्य कथन का उपयोग करता है। आप एक साधारण "1" का भी उपयोग कर सकते हैं—और यह बिल्कुल वैसा ही काम करेगा—लेकिन यह सही कथन के उपयोग को दर्शाता है:

[student@studentvm1 testdir]$ X=0 ; while [ true ] ; do echo $X ; X=$((X+1)) ; done | head
0
1
2
3
4
5
6
7
8
9
[student@studentvm1 testdir]$

इस सीएलआई कार्यक्रम को अब और अधिक समझ में आना चाहिए क्योंकि आपने इसके भागों का अध्ययन कर लिया है। सबसे पहले, यह $X . सेट करता है शून्य करने के लिए यदि इसका मान पिछले प्रोग्राम या CLI कमांड से बचा हुआ है। फिर, तार्किक व्यंजक [ true ] . के बाद से हमेशा 1 का मूल्यांकन करता है, जो सत्य है, करें . के बीच प्रोग्राम निर्देशों की सूची और किया गया हमेशा के लिए निष्पादित किया जाता है—या जब तक आप Ctrl+C . दबाते हैं या अन्यथा प्रोग्राम को सिग्नल 2 भेजें। वे निर्देश एक अंकगणितीय विस्तार हैं जो $X . के वर्तमान मान को प्रिंट करते हैं और फिर इसे एक-एक करके बढ़ा देता है।

Sysadmins के लिए Linux दर्शन . के सिद्धांतों में से एक लालित्य के लिए प्रयास करना है, और लालित्य प्राप्त करने का एक तरीका सादगी है। आप वैरिएबल इंक्रीमेंट ऑपरेटर, ++ . का उपयोग करके इस प्रोग्राम को सरल बना सकते हैं . पहले उदाहरण में, चर का वर्तमान मान मुद्रित किया जाता है, और फिर चर को बढ़ाया जाता है। यह ++ . लगाकर इंगित किया गया है चर के बाद ऑपरेटर:

[student@studentvm1 ~]$ X=0 ; while [ true ] ; do echo $((X++)) ; done | head
0
1
2
3
4
5
6
7
8
9

अब हटाएं | सिर कार्यक्रम के अंत से और इसे फिर से चलाएँ।

इस संस्करण में, इसके मूल्य मुद्रित होने से पहले चर को बढ़ाया जाता है। यह ++ . लगाकर निर्दिष्ट किया जाता है चर से पहले ऑपरेटर। क्या आप अंतर देख सकते हैं?

[student@studentvm1 ~]$ X=0 ; while [ true ] ; do echo $((++X)) ; done | head
1
2
3
4
5
6
7
8
9

आपने दो कथनों को एक एकल में घटा दिया है जो चर के मान को प्रिंट करता है और उस मान को बढ़ाता है। एक डिक्रीमेंट ऑपरेटर भी है, --

लूप को किसी विशिष्ट संख्या पर रोकने के लिए आपको एक विधि की आवश्यकता है। इसे पूरा करने के लिए, वास्तविक अभिव्यक्ति को वास्तविक संख्यात्मक मूल्यांकन अभिव्यक्ति में बदलें। प्रोग्राम लूप को 5 पर रखें और रुकें। नीचे दिए गए उदाहरण कोड में, आप देख सकते हैं कि -le "इससे कम या इसके बराबर" के लिए तार्किक संख्यात्मक संचालिका है। इसका अर्थ है:"जब तक $X 5 से कम या उसके बराबर है, लूप जारी रहेगा। जब $X 6 की वृद्धि, लूप समाप्त हो जाता है।"

[student@studentvm1 ~]$ X=0 ; while [ $X -le 5 ] ; do echo $((X++)) ; done 
0
1
2
3
4
5
[student@studentvm1 ~]$

लूप तक

तक कमांड बहुत हद तक जबकि . जैसा है आज्ञा। अंतर यह है कि यह तब तक लूप करना जारी रखेगा जब तक कि तार्किक अभिव्यक्ति "सत्य" का मूल्यांकन न करे। इस निर्माण का सबसे सरल रूप देखें:

[student@studentvm1 ~]$ X=0 ; until false  ; do echo $((X++)) ; done | head
0
1
2
3
4
5
6
7
8
9
[student@studentvm1 ~]$

यह किसी विशिष्ट मान की गणना करने के लिए तार्किक तुलना का उपयोग करता है:

[student@studentvm1 ~]$ X=0 ; until [ $X -eq 5 ]  ; do echo $((X++)) ; done
0
1
2
3
4
[student@studentvm1 ~]$ X=0 ; until [ $X -eq 5 ]  ; do echo $((++X)) ; done
1
2
3
4
5
[student@studentvm1 ~]$

सारांश

इस श्रृंखला ने बैश कमांड-लाइन प्रोग्राम और शेल स्क्रिप्ट के निर्माण के लिए कई शक्तिशाली उपकरणों की खोज की है। लेकिन इसने बमुश्किल कई दिलचस्प चीजों पर सतह को खरोंच दिया है जो आप बैश के साथ कर सकते हैं; बाकी आप पर निर्भर है।

मैंने पाया है कि बैश प्रोग्रामिंग सीखने का सबसे अच्छा तरीका इसे करना है। एक साधारण प्रोजेक्ट ढूंढें जिसके लिए कई बैश कमांड की आवश्यकता होती है और उनमें से एक सीएलआई प्रोग्राम बनाएं। Sysadmins कई कार्य करते हैं जो स्वयं को CLI प्रोग्रामिंग के लिए उधार देते हैं, इसलिए मुझे यकीन है कि आपको स्वचालित करने के लिए कार्य आसानी से मिल जाएंगे।

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


  1. बैश उपनाम के साथ 7z संपीड़न को सरल कैसे करें

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

  1. अपनी गो-टू कमांड लाइन भाषा के रूप में बैश को पायथन के साथ कैसे बदलें

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

  1. एक्सेल में छात्र डेटाबेस कैसे बनाएं (आसान चरणों के साथ)

    डेटाबेस बड़ी मात्रा में डेटा और जानकारी को मज़बूती से संभाल सकता है। उनमें डेटा के स्तर होते हैं जो वर्कशीट पर समझ से बाहर होंगे क्योंकि वे डेटा को अधिक प्रभावी ढंग से रखते हैं। एक डेटाबेस अक्सर डेटा पुनर्प्राप्त करना आसान बनाने के लिए बनाया जाता है। एक एक्सेल डेटाबेस एक वर्कशीट है जिसमें डेटा की पं