سنتعلم في هذا المقال كيفية استخدام الجمل والعبارات الشرطية الشائعة مثل if و else و case لكتابة سكربتات باش فعالة، ونتعرف على طريقة التعامل مع سيناريوهات متعددة واتخاذ القرارات المناسبة من خلالها.
استخدام الجملة الشرطية if في باش
يعد الشرط if العنصر الأساسي في أي بنية برمجية لاتخاذ القرار، ويمكن كتابة الشرط في باش وفق الصيغة العامة التالية:
if [ condition ]; then your code fi
نلاحظ أن كل عبارات if الشرطية تبدأ في باش بالأمر if وتنتهي بالأمر fi أي if معكوسة. ويجب الانتباه للمسافات الفارغة عند كتابة الجمل الشرطية فهي ذات أهمية، وهذه مواضعها:
- توجد مسافة فارغة قبل الشرط condition المكتوب بين قوسين وبعده، وإذا أهملناها سنحصل على خطأ
- توجد مسافة فارغة قبل وبعد العوامل الشرطية مثل = أو == أو => وعدم الالتزام بها سيعطينا رسالة خطأ مفادها unary operator expected أي يتوقع تشغيل عامل فردي.
لنجرب الآن كتابة سكربت بسيط باسم root.sh، يعرض على الشاشة عبارة "You are root" في حالة واحدة فقط إذا كان المستخدم الذي ينفذ السكربت هو الجذر root:
#!/bin/bash
if [ $(whoami) = 'root' ]; then
echo "You are root"
fi
اعتمدنا في هذا السكربت على الأمر whoami الذي يعطينا اسم المستخدم مُنفّذ السكربت، وكتابته ضمن قوسين هلاليين مع رمز الدولار بالصيغة التالية (command)$ فتعني حصولنا على خرج الأمر بهيئة متغير، تدعى هذه العملية تعويض الأوامر command substitutions وقد تعرفنا عليها في مقال المتغيرات في سكربتات الصدفة باش Bash.
إذًا سيتحقق الشرط الوارد في جملة if ويطبع العبارة المطلوبة في حالة واحدة فقط وهي عندما ينفذ السكربت المستخدم الجذر root، وتظهر الصورة التالية نتيجة التنفيذ:
استخدام الجملة الشرطية if-else في باش
يمكننا تضمين أي تعليمة برمجية نريد تنفيذها عندما لا يتحقق الشرط if في الجملة الشرطية else فإذا عدنا للسكربت السابق root.sh مثلًا، وعدّلنا محتواه حتى يعطينا خرجًا معينًا عند عدم تحقق الشرط، فالسكربت في وضعه الحالي لا يظهر لنا أي نتيجة عند التنفيذ من مستخدم آخر غير الجذر وعندما نعدله على النحو التالي:
#!/bin/bash
if [ $(whoami) = 'root' ]; then
echo "You are root"
else
echo "You are not root"
fi
ونحاول تشغيل السكربت من حساب المستخدم العادي، سنحصل على تنبيه يخبرنا أن المستخدم ليس المستخدم الجذر كما يلي:
kabary@handbook:~$ ./root.sh You are not root
استخدام الجملة الشرطية else-if في باش
تساعدنا الجملة الشرطية else-if على اختبار أكثر من شرط في الوقت نفسه، وتكتب اختصارًا elif. لنلاحظ على سبيل المثال السكربت age.sh التالي الذي يأخذ معامل العمر AGE كوسيط ويعطينا نتيجة حسب الشروط المحددة في if و elif:
#!/bin/bash
AGE=$1
if [ $AGE -lt 13 ]; then
echo "You are a kid."
elif [ $AGE -lt 20 ]; then
echo "You are a teenager."
elif [ $AGE -lt 65 ]; then
echo "You are an adult."
else
echo "You are an elder."
fi
يمكنك العودة لمقال تمرير الوسطاء إلى سكربت باش Bash لمطالعة مزيد من المعلومات عن تمرير الوسطاء لسكربتات باش. لننفذ السكربت الآن مع قيم مختلفة لمتغير العمر AGE ونلاحظ النتائج كما يلي:
kabary@handbook:~$ ./age.sh 11 You are a kid. kabary@handbook:~$ ./age.sh 18 You are a teenager. kabary@handbook:~$ ./age.sh 44 You are an adult. kabary@handbook:~$ ./age.sh 70 You are an elder.
استخدمنا الشرط lt وهو اختصار للعبارة الإنجليزية less than أي أصغر من لاختبار قيمة المتغير AGE$.
وتجدر الإشارة لكوننا نستطيع استخدام الجملة الشرطية elif بقدر ما نريد في بنية else-if، أما else فلا تُكتَب فيها إلا مرة واحدة فقط، وأن كافة جمل if الشرطية ينبغي أن تُغلق باستخدام fi.
استخدام جمل if الشرطية المتداخلة في باش
يُقصد بالجمل الشرطية المتداخلة استخدام جمل if الشرطية داخل جمل if أخرى، لننظر على السكربت التالي weather.sh لتوضيح الأمر:
#!/bin/bash
TEMP=$1
if [ $TEMP -gt 5 ]; then
if [ $TEMP -lt 15 ]; then
echo "The weather is cold."
elif [ $TEMP -lt 25 ]; then
echo "The weather is nice."
else
echo "The weather is hot."
fi
else
echo "It's freezing outside ..."
fi
يُظهِر هذا السكربت عبارات تصف الطقس بحسب درجة الحرارة المعطاة له ضمن الوسيط TEMP، فإذا كانت درجة الحرارة أكبر من 5 درجات فستُفَعَل عندها الجملة الشرطية الداخلية if-elif، دعنا نعطي السكربت بعض القيم المتفاوتة ونلاحظ النتائج:
kabary@handbook:~$ ./weather.sh 0 It's freezing outside ... kabary@handbook:~$ ./weather.sh 8 The weather is cold. kabary@handbook:~$ ./weather.sh 16 The weather is nice. kabary@handbook:~$ ./weather.sh 30 The weather is hot.
استخدام الجملة الشرطية case في باش
الجملة الشرطية case هي بديل مناسب يغني في بعض الحالات التعقيد المصاحب لكثرة استخدام if ضمن السكربت، فالجملة case أسهل في القراءة والإعداد، وهذه صيغتها العامة:
case "variable" in
"pattern1" )
Command … ;;
"pattern2" )
Command … ;;
"pattern2" )
Command … ;;
esac
لننتبه للتالي عند كتابة case:
-
توجد مسافة فارغة وقوس هلالي
)بعد كل حالة أو نمط من أنماط الجملة الشرطيةcase -
تنتهي جميع الأوامر بمسافة فارغة وفاصلة منقوطة مزدوجة
;;والمسافة الفارغة هنا إلزامية -
تنتهي جملة
caseدائمًا بالأمرesacوهو عبارة عن كلمة case معكوسة
أكثر حالات استخدام case عند مطابقة المتغير مع أنماط أو خيارات محددة وواضحة كما في السكربت char.sh التالي:
CHAR=$1 case $CHAR in [a-z]) echo "Small Alphabet." ;; [A-Z]) echo "Big Alphabet." ;; [0-9]) echo "Number." ;; *) echo "Special Character." esac
يقبل هذا السكربت وسيطًا واحدًا هو CHAR، وتطابق الجملة case قيمته مع مجموعة أنماط، لتقرر فيما إذا كان المتغير حرفًا أبجديًا كبيرًا أو صغيرًا، أو عددًا أو محرفًا خاصًا. لنلاحظ نتائج تنفيذ السكربت مع قيم مختلفة للمتغير:
kabary@handbook:~$ ./char.sh a Small Alphabet. kabary@handbook:~$ ./char.sh Z Big Alphabet. kabary@handbook:~$ ./char.sh 7 Number. kabary@handbook:~$ ./char.sh $ Special Character.
يُمثل رمز النجمة * هنا الحالة الافتراضية للجملة case وهو يقابل else في جملة if الشرطية.
شروط الاختبار في باش
تعتمد شروط الاختبار المستخدمة في الجمل الشرطية السابقة في نهاية الأمر على معاملات منطقية، وتختلف طبيعتها حسب نوع البيانات المتعامل معها سواء كانت أعدادًا أو سلاسل نصية أو ملفات، ويبين الجدول التالي أشهر هذه الشروط:
| الشرط | المكافئ |
|---|---|
| a -lt $b$ | قيمة a أصغر من قيمة b |
| a -gt $b$ | قيمة a أكبر من قيمة b |
| a -le $b$ | قيمة a أصغر أو تساوي قيمة b |
| a -ge $b$ | قيمة a أكبر أو تساوي قيمة b |
| a -eq $b$ | قيمة a تساوي قيمة b |
| a -ne $b$ | قيمة a لا تساوي قيمة b |
| e $FILE- | المتغير FILE$ موجود |
| d $FILE- | المتغير FILE$ موجود وهو مجلد |
| f $FILE- | المتغير FILE$ موجود وهو ملف عادي |
| L $FILE- | المتغير FILE$ موجود وهو رابط مرن soft link |
| $STRING1 = $STRING2 | قيمة السلسلة النصية STRING1 تساوي قيمة السلسلة النصية STRING2 |
| $STRING1 != $STRING2 | قيمة السلسلة النصية STRING1 لا تساوي قيمة السلسلة النصية STRING2 |
| -z $STRING1 | قيمة السلسلة النصية STRING1 فارغة |
لا يتوجب حفظ هذه الشروط عن ظهر قلب فهي متوفرة في دليل مساعد يشرح طريقة كتابتها عندما نحتاجها، ويمكننا الوصول إليه بالتعليمة التالية:
kabary@handbook:~$ man test
لنطبق مثالًا عمليًّا على شروط باش، سننشئ السكربت filetype.sh الذي يبين طبيعة العنصر المعطى له إذا كان ملفًا أو مجلدًا أو رابطًا مرنًا soft link:
#!/bin/bash
if [ $# -ne 1 ]; then
echo "Error: Invalid number of arguments"
exit 1
fi
file=$1
if [ -f $file ]; then
echo "$file is a regular file."
elif [ -L $file ]; then
echo "$file is a soft link."
elif [ -d $file ]; then
echo "$file is a directory."
else
echo "$file does not exist"
fi
تفحص الجملة الشرطية الموجودة في بداية السكربت عدد الوسطاء الممررة له، وإذا تبين عدم وجود أي وسيط أو كان عدد الوسطاء أكبر من 1 فستُنهي هذه الجملة تنفيذ السكربت دون الانتقال للخطوة التالية، وتعطي المستخدم رسالة تحذيرية تطالبه بالتأكد من صحة الوسطاء المقدمة.
لننفذ السكربت على عناصر مختلفة ونتفقد النتائج:
kabary@handbook:~$ ./filetype.sh weather.sh weather.sh is a regular file. kabary@handbook:~$ ./filetype.sh /bin /bin is a soft link. kabary@handbook:~$ ./filetype.sh /var /var is a directory. kabary@handbook:~$ ./filetype.sh Error: Invalid number of arguments
طريقة كتابة جملة if-else في سطر واحد
يمكنك استخدام الجمل الشرطية if-else في ورؤية نتائجها في الصدفة shell مباشرةً دون الحاجة لكتابتها في سكربت خاص وتنفيذه عند اللزوم، وهذا مثال:
if [ $(whoami) = 'root' ]; then
echo "You are root"
else
echo "You are not root"
fi
بوسعنا كتابة هذا المثال في سطر واحد لتسهيل التعامل معه، ويجري ذلك بإضافة فاصلة منقوطة بين كل أمر وآخر كما يلي:
if [ $(whoami) = 'root' ]; then echo "root"; else echo "not root"; fi
نستطيع الآن تنفيذه في الصدفة مباشرةً، لننسخه ونلصقه في الطرفية terminal ونلاحظ النتيجة.
الخلاصة
حاولنا في هذه المقالة تكوين فكرةً عامة عن استخدام الجمل الشرطية في سكربتات باش من خلال أمثلة عملية متنوعة، ولفهم الموضوع بشكل أفضل ننصح بالتفكير بحالات اتخاذ قرار جديدة ومحاولة كتابة سكربتات مناسبة لها، فهذا من شأنه تعزيز فهم الموضوع والتعامل معه بكفاءة.
ترجمة -وبتصرف- للمقال Decision Making With If Else and Case Statements.

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