आपकी स्क्रिप्ट बैश शेल की तीन विशेषताओं का उपयोग करती है जो सभी बॉर्न-शैली के गोले द्वारा प्रदान नहीं की जाती हैं। जैसा कि हेमायल कहते हैं , आप केवल उस स्क्रिप्ट को 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 122
a
z
- शक्तिशाली
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 ]
)।