आपकी स्क्रिप्ट बैश शेल की तीन विशेषताओं का उपयोग करती है जो सभी बॉर्न-शैली के गोले द्वारा प्रदान नहीं की जाती हैं। जैसा कि हेमायल कहते हैं , आप केवल उस स्क्रिप्ट को bashइसके बजाय चला सकते हैं sh। शीर्ष पर आपकी हैशबैंग लाइन ( #!/bin/bash) निर्दिष्ट है, bashलेकिन केवल तभी प्रभावी है जब आप स्क्रिप्ट निष्पादित करते हैं, जैसा कि हेमायल ने समझाया था । यदि आप स्क्रिप्ट का नाम पास करते हैं sh, shतो स्वचालित रूप से कॉल नहीं करेगा bash, लेकिन बस स्क्रिप्ट चलाएगा। ऐसा इसलिए है क्योंकि एक बार जब आपकी स्क्रिप्ट वास्तव में चल रही होती है, तो हैशबैंग लाइन का कोई प्रभाव नहीं पड़ता है ।
आपका अन्य विकल्प, यदि आपको पूरी तरह से पोर्टेबल स्क्रिप्ट लिखने की ज़रूरत है जो बैश सुविधाओं पर निर्भर नहीं है, तो अपनी स्क्रिप्ट को बदलना है ताकि यह उनके बिना काम करे। आपके द्वारा उपयोग की जाने वाली बैश विशेषताएं हैं:
- एक सरणी । यह पहली बार आया था, इसलिए जब आप अपने स्क्रिप्ट को डैश शेल से चलाने का प्रयास करते हैं तो यह त्रुटि उत्पन्न होती है । कोष्ठबद्ध अभिव्यक्ति
( {a..z} ), जिसे आप असाइन करते हैं chars, एक सरणी बनाता है, और ${chars[i]}, जो आपके लूप में दिखाई देता है, उसमें अनुक्रमित होता है।
- ब्रेस विस्तार। बैश में, और भी कई अन्य गोले में,
{a..z}का विस्तार किया जाता है a b c d e f g h i j k l m n o p q r s t u v w x y z। हालाँकि, यह बॉर्न-शैली के गोले की एक सार्वभौमिक (या मानकीकृत) विशेषता नहीं है, और डैश इसका समर्थन नहीं करता है।
- सी-शैली वैकल्पिक
for-लूप वाक्य रचना । हालांकि के आधार पर गणित विस्तार है, जो है बैश के लिए विशिष्ट ही नहीं (हालांकि कुछ बहुत पुरानी, गैर POSIX अनुरूप गोले यह नहीं है, या तो), सी शैली forपाश है एक बैश-वाद और व्यापक रूप से करने के लिए पोर्टेबल नहीं है अन्य गोले।
बैश व्यापक रूप से उपलब्ध है, खासकर GNU / Linux सिस्टम पर जैसे Ubuntu, और (जैसा कि आपने देखा है) macOS और कई अन्य प्रणालियों पर भी उपलब्ध है। यह देखते हुए कि आप बैश-विशिष्ट सुविधाओं का कितना उपयोग कर रहे हैं, आप शायद उनका उपयोग करना चाहते हैं, और बस सुनिश्चित करें कि आप अपनी स्क्रिप्ट चलाने के दौरान बैश का उपयोग कर रहे हैं (या कुछ अन्य शेल जो आपके द्वारा उपयोग की जा रही सुविधाओं का समर्थन करते हैं)।
हालाँकि, यदि आप चाहें, तो आप उन्हें पोर्टेबल निर्माणों से बदल सकते हैं। सरणी और सी-स्टाइल forलूप को बदलना आसान है; बिना ब्रेस विस्तार (और अपनी स्क्रिप्ट में उन्हें हार्ड-कोडिंग के बिना) अक्षरों की श्रेणी उत्पन्न करना एक हिस्सा है जो थोड़ा मुश्किल है।
सबसे पहले, यहां एक स्क्रिप्ट है जो सभी निचले-केस लैटिन अक्षरों को प्रिंट करती है:
#!/bin/sh
for i in $(seq 97 122); do
printf "\\$(printf %o $i)\n"
done
seqआदेश संख्यात्मक अनुक्रम उत्पन्न करता है। कमांड प्रतिस्थापन$( ) करता है , इसलिए के आउटपुट के साथ बदल दिया जाता है । इन के माध्यम से चरित्र कोड हैं ।$(seq 97 122)seq 97 122az
- शक्तिशाली
printfकमांड वर्ण कोड को अक्षरों में बदल सकता है (उदाहरण के लिए, printf '\141'प्रिंट्स a, इसके बाद एक नई पंक्ति ), लेकिन कोड ऑक्टल में होने चाहिए , जबकि seqकेवल दशमलव में आउटपुट होते हैं । इसलिए मैंने printfदो बार उपयोग किया है: आंतरिक printf %o $iदशमलव संख्या (द्वारा प्रदान की गई seq) को ऑक्टल में रूपांतरित करता है, और बाहरी कमांड में प्रतिस्थापित किया जाता है printf। (हालांकि हेक्साडेसिमल का उपयोग करना भी संभव है , यह कोई सरल नहीं है और कम पोर्टेबल लगता है ।)
printf\उस कोड के साथ एक अष्टक संख्या और उसके बाद \nएक नई पंक्ति के रूप में व्याख्या करता है। लेकिन खोल भी \बच चरित्र के रूप में उपयोग करता है । एक \के सामने $नहीं कर पाएगा $से होने के लिये एक विस्तार के कारण (इस मामले में आदेश प्रतिस्थापन ), लेकिन मुझे लगता है कि को रोकने के लिए नहीं करना चाहते हैं, तो मैं इसे किसी अन्य के साथ बच गए \; इसका कारण है \\। \इससे पहले दूसरे nको भागने की जरूरत नहीं है, क्योंकि, इसके विपरीत \$, \nएक डबल-उद्धृत स्ट्रिंग में शेल के लिए विशेष अर्थ नहीं है।
- शेल प्रोग्रामिंग में डबल कोट और बैकस्लैश का उपयोग कैसे किया जाता है, इस बारे में अधिक जानकारी के लिए, अंतर्राष्ट्रीय मानक में उद्धृत करने पर अनुभाग देखें । बैश संदर्भ मैनुअल में 3.1.2 कोटेशन भी देखें , विशेष रूप से 3.1.2.1 एस्केप कैरेक्टर और 3.1.2.3 डबल कोट्स । (यहां पूरा खंड , संदर्भ में है।) ध्यान दें कि एकल उद्धरण ( ) भी सिंटैक्स को उद्धृत करते हुए शेल का एक महत्वपूर्ण हिस्सा है, मैं बस उस स्क्रिप्ट में उनका उपयोग नहीं करता हूं।
'
यह अधिकांश यूनिक्स जैसी प्रणालियों के लिए पोर्टेबल है और यह निर्भर नहीं करता है कि आप किस बॉर्न-शैली के शेल का उपयोग करते हैं। हालाँकि, कुछ यूनिक्स जैसे सिस्टम seqडिफ़ॉल्ट रूप से स्थापित नहीं होते हैं (वे jotइसके बजाय उपयोग करना चाहते हैं, जो डिफ़ॉल्ट रूप से अधिकांश GNU / लिनक्स सिस्टम द्वारा स्थापित नहीं है)। exprपोर्टेबिलिटी को आगे बढ़ाने के लिए या अंकगणितीय प्रतिस्थापन के साथ आप एक लूप का उपयोग कर सकते हैं , यदि आपको आवश्यकता हो तो:
#!/bin/sh
i=97
while [ $i -le 122 ]; do
printf "\\$(printf %o $i)\n"
i=$((i + 1))
done
यह आदेश में लूपिंग जारी रखने के लिए आदेश केwhile साथ एक लूप का उपयोग करता है ।[$i
पूरे वर्णमाला को प्रिंट करने के बजाय, आपकी स्क्रिप्ट एक चर को परिभाषित करती है nऔर पहले $nनिचले-मामले के अक्षरों को प्रिंट करती है । यहां आपकी स्क्रिप्ट का एक संस्करण है जो डैश-आधारित सुविधाओं और डैश पर काम करने पर निर्भर करता है, लेकिन इसके लिए आवश्यक है seq:
#!/bin/sh
n=3 start=97
for i in $(seq $start $((start + n - 1))); do
printf "\\$(printf %o $i)\n"
done
nपरिवर्तनों के मूल्य को समायोजित करना कि आपकी स्क्रिप्ट में कितने अक्षर मुद्रित हैं।
यहां एक ऐसा संस्करण है जिसकी आवश्यकता नहीं है seq:
#!/bin/sh
n=3 i=97 stop=$((i + n))
while [ $i -lt $stop ]; do
printf "\\$(printf %o $i)\n"
i=$((i + 1))
done
वहाँ, अंतिम पत्र के चरित्र कोड से $stopएक अधिक है जिसे मुद्रित किया जाना चाहिए, इसलिए मैं कमांड के साथ (कम या बराबर) के -ltबजाय -le(कम से कम ) का उपयोग करता हूं [। (इसे बनाने stop=$((i + n - 1))और उपयोग करने के लिए भी काम किया होगा [ $i -le $stop ])।