اذهب إلى المحتوى

الحلقات Loops ضرورية في أي لغة برمجة، ولها حالات استخدام متعددة في سكربتات باش سنتعلمها معًا في هذا المقال، وسنتعرف على حلقات For و While و Until، وعلى كيفية التحكم بالحلقات باستخدام تعليمات break و continue، بالإضافة لطريقة كتابة الحلقات اللانهائية، وكيف أنها قد تشير في بعض الأحيان لوجود أخطاء في كتابة السكربت.

حلقات For في باش

حلقة for هي واحدة من ثلاثة أنواع من الحلقات التكرارية التي يمكننا استخدامها في سكربتات باش، وهي تكتب بطريقتين:

  • حلقة for المكتوبة بأسلوب لغة C
  • حلقة for المعتمدة على قائمة أو مجال محدد من العناصر

كتابة حلقة for بأسلوب لغة C في سكربتات باش

نكتب هذا النوع من حلقات for بالطريقة نفسها التي نكتبها في لغات البرمجة C و ++C وفق الصيغة العامة التالية:

for ((initialize ; condition ; increment)); do
[COMMANDS]
done

إذا طبقنا الصيغة العامة السابقة على المثال أدناه، فإن تنفيذ الحلقة الموجودة فيه سيعرض عبارة "Hello Friend" عشر مرات على شاشة الطرفية:

for ((i = 0 ; i < 10 ; i++)); do
    echo "Hello Friend"
done

لنفسر الشيفرة السابقة: القيمة الابتدائية لمتغير الحلقة هي 0، وشرط التكرار أن لا تتجاوز قيمة المتغير العدد 10، ومقدار الزيادة هو 1، وبالتالي في كل مرة يتحقق فيها شرط الحلقة سيُنفذ الأمر البرمجي وهو في حالتنا عرض العبارة Hello Friend على الشاشة وتزداد قيمة متغير الحلقة i بمقدار واحد، ثم يُفحص الشرط من جديد وهكذا حتى الوصول للحد الأعلى أي 10.

وهذه نتيجة تنفيذ الحلقة:

kabary@handbook:~$ bash hello.sh 
Hello Friend
Hello Friend
Hello Friend
Hello Friend
Hello Friend
Hello Friend
Hello Friend
Hello Friend
Hello Friend
Hello Friend

كتابة حلقة for المعتمدة على القوائم في سكربتات باش

تفيدنا حلقة for المكتوبة بهذه الطريقة في الحالات التي نتعامل فيها مع قائمة معروفة العناصر، مثل: مجموعة ملفات أو مجموعة سلاسل نصية، أو مجال محدد من الأعداد، أو مصفوفة، أو ربما مخرجات ثابتة لأمر معين أو غير ذلك، ولها الصيغة العامة التالية:

for item in [LIST]; do
[COMMANDS]
done

يبين المثال أدناه الحلقة نفسها التي تعاملنا معها في الفقرة السابقة ولكنها مكتوبة هذه المرة بطريقة القائمة:

for i in {1..10}; do
    echo "Hello Friend"
done

وهذا مثال آخر حيث يعرض السكربت var.sh التالي جميع الملفات الموجودة في المجلد var/:

#!/bin/bash

for i in /var/*; do
    echo $i 
done

وسنحصل في الخرج على نتيجة تشبه ما يلي:

kabary@handbook:~$ ./var.sh
/var/backups
/var/cache
/var/crash
/var/lib
/var/local
/var/lock
/var/log
/var/mail
/var/metrics
/var/opt
/var/run
/var/snap
/var/spool
/var/tmp

حلقات While في باش

هذه هي الصيغة العامة لحلقة while في باش:

while [ condition ]; do
[COMMANDS]
done

لنطبق مثالًا عمليًّا: يعرض السكربت التالي المضاعفات العشرة الأولى للعدد 3:

#!/bin/bash

num=1
while [ $num -le 10 ]; do
    echo $(($num * 3))
    num=$(($num+1))
done

وسيكون الخرج كما يلي:

kabary@handbook:~$ ./3x10.sh
3
6
9
12
15
18
21
24
27
30

لنُحلّل السكربت أعلاه، في البداية أعطينا المتغير num القيمة الابتدائية 1، وحددنا شرط تكرار الحلقة بأن لا تتجاوز قيمة المتغير العدد 10، وبناءً على ذلك سيُنَفَذ الأمران الموجودان في جسم الحلقة وهما أولًا إظهار ناتج ضرب قيمة المتغير num بالعدد 3 على الشاشة، وثانيًا زيادة قيمة num بمقدار 1، ويُعاد تنفيذهما مرارًا وتكرارًا طالما أن شرط الحلقة محقق.

حلقات Until في باش

النوع الثالث من الحلقات التكرارية باش هو until، وليس الحلقة do-while التي اعتاد عليها مبرمجو لغة C و ++C، وكما نلاحظ أدناه فالصيغة العامة لحلقة until مطابقة تمامًا لصيغة كتابة حلقة while:

until [ condition ]; do
[COMMANDS]
Done

ويكمن الفرق بينهما في طريقة تعامل كل حلقة مع نتيجة اختبار الشرط فيما إذا كان محققًا أو غير محقق، ففي الحلقة while يستمر التنفيذ طالما أن شرط الحلقة محقق، وعلى العكس تمامًا في الحلقة until إذ يستمر التنفيذ طالما أن الشرط غير محقق.

لنكتب الآن السكربت السابق باستخدام الحلقة until بدلًا من while، دقق جيدًا في الشرط فهو جوهر الاختلاف بين السكربتين:

#!/bin/bash

num=1
until [ $num -gt 10 ]; do
    echo $(($num * 3))
    num=$(($num+1))
done

الشرط هنا هو أن تكون قيمة المتغير num أكبر من 10، بينما كان الشرط في سكربت while هو أن تكون قيمة المتغير num أصغر من 10وهما كما تلاحظ عكس بعضهما تمامًا.

حالات شائعة لاستخدام الحلقات في باش

بعد أن تعرفنا على أساسيات الحلقات، سنعرض بعضًا من أشهر استخداماتها في باش:

إظهار عناصر مصفوفة بواسطة سكربت باش

تُعدّ الحلقة for خيارًا مناسبًا لعرض عناصر أي مصفوفة في باش، يمكن الرجوع لمقالنا استخدام المصفوفات في باش Bash لمعرفة كيفية إنشاء مصفوفات باش والتعامل معها.

ألقِ نظرة على السكربت prime.sh التالي، إنه يتضمن مصفوفة تسمى prime وحلقة for تمر على عناصر المصفوفة واحدًا تلو الآخر وتُظهرهم على الشاشة بواسطة الأمر echo:

#!/bin/bash

prime=(2 3 5 7 11 13 17 19 23 29)
for i in "${prime[@]}"; do
    echo $i
done 

وسيكون الخرج كما يلي:

kabary@handbook:~$ ./prime.sh
2
3
5
7
11
13
17
19
23
29

استخدام break و continue في حلقات باش

تساعدنا تعليمات break و continue على إنهاء تنفيذ الحلقة قبل الأوان أو تخطي بعضًا من تكراراتها لأغراض تخدم برنامجنا.

توقف التعليمة break تنفيذ الحلقة وتنقل التنفيذ إلى التعليمة التالية في البرنامج، فعلى سبيل المثال ستعرض الحلقة التالية الأعداد من واحد إلى ثلاثة فقط على شاشة الطرفية:

for ((i=1;i<=10;i++)); do
    echo $i
    if [ $i -eq 3 ]; then
        break
    fi
done

وتساعدنا التعليمة continue على تجاوز بعض التكرارات، فكلما وصل تسلسل التنفيذ إلى continue تُهمَل الأوامر التي تليها والتي تقابل قيمًا معينة للمتغير نود تجاوزها، ويُكرر تنفيذ الحلقة بعد زيادة قيمة المتغير.

يبين السكربت odd.sh التالي كيفية استخدام continue لتخطي الأعداد الزوجية وإظهار الأعداد الفردية فقط من بين الأعداد من صفر إلى عشرة:

#!/bin/bash
for ((i=0;i<=10;i++)); do
    if [ $(($i % 2)) -ne 1 ]; then
        continue
    fi
    echo $i
done

وستحصل على هذا الخرج:

kabary@handbook:~$ ./odd.sh
1
3
5
7
9

الحلقات اللانهائية في باش

الحلقات اللانهائية Infinite Loops هي حلقات دائمة التكرار بدون نهاية لأن شرط تكرارها محقق دائمًا. قد يبني المستخدم حلقات لانهائية عن قصد لأهداف معينة، لكن معظم الحلقات النهائية في واقع الأمر تظهر نتيجة أخطاء بشرية غير مقصودة.

الهدف من إنشاء الحلقة التالية مثلًا هو إظهار الأرقام من واحد إلى عشرة على شاشة الطرفية لكن بترتيب تنازلي، إذا دققنا فيها سنكتشف خطأ يوقع المستخدم ضحية تكرار لا نهائي للحلقة:

for ((i=10;i>0;i++)); do
    echo $i
done 

إذا دققنا في الكود أعلاه سنلاحظ أن مُنشئ الحلقة هنا يزيد قيمة المتغير i بمقدار واحد بعد كل تنفيذ بدلًا من إنقاصها بمقدار واحد ليصل في النهاية إلى القيمة صفر وهي شرط انتهاء الحلقة، فحتى تعمل الحلقة بالصورة المطلوبة علينا استبدال ++i بالتعليمة --i لتصبح كما يلي:

for ((i=10;i>0;i--)); do
    echo $i
done 

قد تفرض علينا متطلبات العمل إنشاء حلقات لا نهائية لانتظار تحقق شروط معينة على النظام مثلًا أو لأسباب أخرى، وبصرف النظر عن السبب إذا احتجنا لإنشاء هذا النوع من الحلقات فيمكننا ذلك باستخدام إحدى الصيغ التالية.

صيغة بناء حلقة لا نهائية باستخدام حلقة for:

for ((;;)); do
    [COMMANDS]
done 

صيغة بناء حلقة لا نهائية باستخدام حلقة while:

while [ true ]; do
    [COMMANDS]
done

الخلاصة

انتهى مقالنا الخاص بالحلقات التكرارية في سكربتات باش، عرضنا فيه الحلقات الأساسية الثلاث مع بعض الأمثلة العملية ووضحنا حالات الاستخدام الخاصة بكل حلقة، ندعوك لمتابعة المقال التالي حول الدوال في باش وتطبيق المزيد من المفاهيم المتقدمة.

ترجمة -وبتصرف- للمقال Loops in Bash.

اقرأ أيضًا


تفاعل الأعضاء

أفضل التعليقات

لا توجد أية تعليقات بعد



انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أضف تعليق

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • أضف...