حلقة while في Bash

من موسوعة حسوب
< Bash
مراجعة 00:33، 7 سبتمبر 2018 بواسطة أسامه-دمراني (نقاش | مساهمات) (مراجعة 6: إضافة تصانيف)
(فرق) → مراجعة أقدم | المراجعة الحالية (فرق) | مراجعة أحدث ← (فرق)
اذهب إلى التنقل اذهب إلى البحث

كيفية عمل حلقة while

تسمح حلقة while التكرارية بالتنفيذ المتكرر لقائمة أوامر طالما أن الأمر المتحكم في حلقة while يُنفَّذ بنجاح (حالة خروجه صفر). والبنية اللغوية لهذه الحلقة هي:

while CONTROL-COMMAND; do CONSEQUENT-COMMANDS; done

حيث يرمز CONTROL-COMMAND -وهو الأمر الذي سيتحكم في الحلقة- إلى أي أمر يخرج بحالة فشل أو نجاح، بينما قد تكون CONSEQUENT-COMMANDS -وهي الأوامر التي ستُكرَّر- أي برنامج أو برنامج للصدفة أو أحد بُنى الصدفة المختلفة.

وتخرج الحلقة فور فشل الأمر المتحكِّم فيها، وإن كانت الحلقة في برنامج للصدفة فإن الأمر الذي يلي عبارة done يُنفَّذ بعد انتهاء الحلقة بسبب فشل الأمر المتحكم.

تكون حالة الإعادة هي نفسها حالة الخروج لآخِر أمر من الأوامر التابعة (CONSEQUENT-COMMANDS)، أو تكون صفرًا لإن لم ينفَّذ أي أمر.

أمثلة

مثال بسيط لاستخدام while

إليك مثالًا بسيطًا يشرح استخدام حلقة while:

#!/bin/bash

# يفتح هذا البرنامج أربع نوافذ للطرفية.

i="0"

while [ $i -lt 4 ]
do
    xterm &
    i=$[$i+1]
done

حلقات while المتداخلة

كُتب المثال التالي من أجل نسخ صور التقطت بواسطة كاميرا ويب إلى مجلد في خادم ويب، إذ تلتقط صورة كل خمس دقائق، وكل ساعة يُنشأ مجلد جديد يحمل صور تلك الساعة، كما يُنشأ مجلد كل يوم يحتوي على 24 مجلد فرعي. يعمل البرنامج في الخلفية:

#!/bin/bash

# ينسخ هذا البرنامج الملفات من مجلد المنزل الخاص بي إلى مجلد في خادم ويب.
# (استخدم مفاتيح ssh و scp للمجلد عن بعد)
# يُنشأ مجلد جديد في كل ساعة

PICSDIR=/home/hsoub/pics
WEBDIR=/var/www/hsoub/webcam

while true; do 
	DATE=`date +%Y%m%d`
	HOUR=`date +%H`
	mkdir $WEBDIR/"$DATE"
	
	while [ $HOUR -ne "00" ]; do 
		DESTDIR=$WEBDIR/"$DATE"/"$HOUR"
		mkdir "$DESTDIR"
		mv $PICDIR/*.jpg "$DESTDIR"/
		sleep 3600
		HOUR=`date +%H`
	done
done

لاحظ استخدام عبارة true، هذا يعني: تابع التنفيذ حتى تُقاطع العملية بالقوة، عن طريق أمر kill أو Ctrl+c. المثال التالي ينشئ ملفات، ويمكن أن يُستخدم لاختبارات المحاكاة:

#!/bin/bash

# يُنشئ هذا البرنامج ملفًا كل خمس دقائق

while true; do
    touch pic-`date +%s`.jpg
    sleep 300
done

لاحظ استخدام أمر date لإنشاء أنواعًا مختلفة من أسماء الملفات والمجلدات، انظر صفحات man للمزيد من الشرح.

استخدم النظام

كان المثال السابق للشرح فقط، أما عمليات التفقّد الدورية يمكن تنفيذها باستخدام أداة cron. لا تنسى توجيه الخرج والأخطاء عند استخدام برامج تُنفّذ من ملف crontab الخاص بك!

استخدام مُدخلات لوحة المفاتيح للتحكم في حلقة while

يمكن تفسير البرنامج التالي بواسطة المستخدم عند إدخال ctrl+c:

#!/bin/bash

# هذا البرنامج يطبع أمثالًا ونصائح

FORTUNE=/usr/games/fortune

while true; do
echo "On which topic do you want advice?"
cat << topics
politics
startrek
kernelnewbies
sports
bofh-excuses
magic
love
literature
drugs
education
topics

echo
echo -n "Make your choice: "
read topic
echo
echo "Free advice on the topic of $topic: "
echo
$FORTUNE $topic
echo

done

يُستخدم مستند here لعرض خيارات مختلفة على المستخدم ليختار منها -مستند here أو heredoc هو طريقة لتغذية برنامج للصدفة بمحتوي قصير بدون كتابته في ملف منفصل-، وكما ذكرنا قبل قليل فإن عبارة true تكرر الأوامر من قائمة الأوامر التابعة مرة بعد مرة.

حساب المتوسط

يحسب هذا البرنامج متوسط مدخلات المستخدم والتي تُختبر قبل أن تُنفَّذ، فإن كان المُدخَل خارج النطاق فإن رسالة تُطبع بذلك، أما إن ضغط المستخدم على مفتاح q فإن الحلقة تخرج:

#!/bin/bash

# احسب متوسط سلسلة أرقام.

SCORE="0"
AVERAGE="0"
SUM="0"
NUM="0"

while true; do

  echo -n "Enter your score [0-100%] ('q' for quit): "; read SCORE;

  if (("$SCORE" < "0"))  || (("$SCORE" > "100")); then
    echo "Be serious.  Common, try again: "
  elif [ "$SCORE" == "q" ]; then
    echo "Average rating: $AVERAGE%."
    break
  else
    SUM=$[$SUM + $SCORE]
    NUM=$[$NUM + 1]
    AVERAGE=$[$SUM / $NUM]
  fi

done

echo "Exiting."

لاحظ كيف تُركت المتغيرات في الأسطر الأخيرة بدون علامات تنصيص من أجل العمليات الحسابية.

انظر أيضًا

مصادر