Bash में लूप करने के दो तरीके हैं:
for लूपआइटम की किसी सूची पर इटरेशन करने के लिए हम for लूप का उपयोग करते हैं।
for varname in words; do COMMANDS; done
words को वर्ड स्प्लिटिंग और फाइलनेम एक्सपैंशन की मदद से एक्सपैंड किया जाता है (जिसके बारे में हमने Quoting कॉन्सेप्ट में सीखा था)।
बारी-बारी से हर शब्द varname में असाइन किया जाता है, और COMMANDS चलाए जाते हैं।
यहाँ कुछ उदाहरण दिए गए हैं जो दिखाते हैं कि for लूप कब काम आ सकता है
फाइलों के एक समूह पर कुछ कमांड चलाना।
# source all the bash library files in the current directory
for file in ./*.bash; do
source "$file"
done
किसी स्क्रिप्ट या फंक्शन के हर पैरामीटर पर कुछ कमांड चलाना।
for arg in "$@"; do
echo "argument: ${arg}"
done
किसी कमांड के आउटपुट में व्हाइटस्पेस से अलग किए गए हर शब्द के लिए कुछ कमांड चलाना।
for i in $(seq 10); do
echo "${i} squared is $((i * i))"
done
इस तरीके के बारे में कुछ चेतावनियाँ हम आगे देखेंगे।
for लूपBash में अंकगणितीय लूप भी होता है। यह दूसरी प्रोग्रामिंग भाषाओं से थोड़ा-बहुत परिचित लगेगा।
for ((INITIALIZATION; CONDITION; INCREMENT)); do COMMANDS; done
Bash में दोहरे ब्रैकेट अंकगणितीय संदर्भ दर्शाते हैं (Bash के अंकगणित के बारे में हम आगे किसी कॉन्सेप्ट में और देखेंगे)।
seq वाला ऊपर का उदाहरण ऐसे लिखा जा सकता है
for ((i = 1; i <= 10; i++)); do
echo "${i} squared is $((i * i))"
done
for का उपयोग कब न करेंयह एक ऐसा एंटी-पैटर्न है जो आप अक्सर देखेंगे: cat के आउटपुट पर इटरेशन करना।
for line in $(cat some.file); do
do_something_with "$line"
done
यह दो कारणों से गलत है।
for लूप फाइल की लाइनों पर नहीं, बल्कि फाइल के शब्दों पर इटरेशन कर रहा है।जैसा कि हमने Quoting कॉन्सेप्ट में सीखा, वर्ड स्प्लिटिंग को IFS वेरिएबल से नियंत्रित किया जा सकता है, और फाइलनेम एक्सपैंशन को बंद किया जा सकता है।
लेकिन यह एक नाज़ुक हल होता है।
किसी फाइल की लाइनों पर इटरेशन करने के लिए for गलत तरीका है।
फाइल पढ़ने का स्वाभाविक तरीका while लूप है।
while लूपकुछ शर्त के सही रहने तक कमांड के एक क्रम को दोहराने के लिए while का उपयोग कीजिए।
while CONDITION_COMMANDS; do COMMANDS; done
जैसे if के साथ होता है (जैसा कि हमने Conditionals कॉन्सेप्ट में सीखा), CONDITION_COMMANDS के लिए कोई खास सिंटैक्स नहीं होता।
कमांड सूची का एग्ज़िट स्टेटस तय करेगा कि यह "सही" है या "गलत"।
break कमांड लूप से बाहर निकाल देता है।
लूप के done टर्मिनेटर के बाद वाले कमांड से कंट्रोल फिर शुरू हो जाता है।
continue कमांड लूप के अगले इटरेशन पर पहुँचा देता है।
जैसा कि बताया गया, फाइल पढ़ने का स्वाभाविक तरीका while लूप है।
while IFS= read -r line; do
do_something_with "$line"
done < some.file
फाइल की सामग्री < रीडायरेक्शन के ज़रिए लूप को इनपुट के रूप में दी जाती है।
read कमांड "सही" लौटाता है अगर वह अपने इनपुट से पूरी लाइन पढ़ पाता है।
जब इनपुट खत्म हो जाता है, या अगर आखिरी लाइन बिना किसी नई लाइन के खत्म होती है, तो read "गलत" लौटाता है।
फाइल की लाइनें पढ़ने का वाकई स्वाभाविक तरीका, भले ही आखिरी लाइन नई लाइन पर खत्म न हो, यह है
while IFS= read -r line || [[ -n "$line" ]]; do ...
-r ऑप्शन read को बताता है कि बैकस्लैश सीक्वेंस को बदलना नहीं है: बैकस्लैश सिर्फ एक आम अक्षर है।
IFS= खाली स्ट्रिंग को IFS में सिर्फ read कमांड की अवधि के लिए असाइन करता है।
यह अस्थायी रूप से वर्ड स्प्लिटिंग बंद कर देता है, ताकि आने वाली टेक्स्ट लाइन में शुरू या आखिर में जो भी व्हाइटस्पेस है वह सुरक्षित रहे।
untiluntil कंस्ट्रक्ट कमांड के क्रम को तब तक दोहराता है जब तक कोई शर्त गलत रहती है।
लूप जब तक शर्त सही नहीं हो जाती, तब तक दोहराता है।
until CONDITION_COMMANDS; do COMMANDS; done
until का उपयोग शायद ही किया जाता है।
इसके बजाय "while not" लूप का उपयोग ज़्यादा आम है।
while ! CONDITION_COMANDS; do ...
कभी-कभी आप हमेशा के लिए लूप चलाना चाहते हैं। इसे करने के दो तरीके हैं।
ऐसा while लूप जिसकी शर्त का एग्ज़िट स्टेटस हमेशा सफल रहता है
while true; do ...
खाली एक्सप्रेशन वाला अंकगणितीय for लूप
for ((;;)); do ...
डू-वाइल के लिए कोई अलग कंस्ट्रक्ट नहीं है, लेकिन आप इसी असर को ऐसे पा सकते हैं:
while true; do
COMMANDS
if END_CONDITION; then
break
fi
done