آماده باشید غافلگیر نشوید. این درس، درس سنگینی خواهد بود!
در درس قبلیِ کنترل جریان، در باره فرمان if و چگونگی استفاده از آن برای تغییر دادن جریان برنامه نسبت به وضعیت خروج یک فرمان، آموختیم. در اصطلاحات برنامهنویسی، این نوع کنترل جریان
یک نوعِ دوم و پیچیدهتر از انشعاب به نام
شما میتوانید این نوع انشعاب را با چندین جمله if طرحریزی کنید. در مثال پایین، ما ورودی کاربر را ارزیابی میکنیم:
#!/bin/bash echo -n "Enter a number between 1 and 3 inclusive > " read character if [ "$character" = "1" ]; then echo "You entered one." elif [ "$character" = "2" ]; then echo "You entered two." elif [ "$character" = "3" ]; then echo "You entered three." else echo "You did not enter a number between 1 and 3." fi
خیلی دلچسب نیست.
خوشبختانه، پوسته یک راهحل بیشتر برازنده برای این مورد فراهم میکند. فرمان داخلی به نام case را فراهم میکند، که در آن میتوانید یک برنامه همارز برنامه فوق بسازید:
#!/bin/bash echo -n "Enter a number between 1 and 3 inclusive > " read character case $character in 1 ) echo "You entered one." ;; 2 ) echo "You entered two." ;; 3 ) echo "You entered three." ;; * ) echo "You did not enter a number between 1 and 3." esac
فرمان case دارای قالب زیر است:
case word in patterns ) commands ;; esac
case به طور انتخابی جملات را در صورتیکه
#!/bin/bash echo -n "Type a digit or a letter > " read character case $character in # بررسی برای حروف [[:lower:]] | [[:upper:]] ) echo "You typed the letter $character" ;; # بررسی برای ارقام [0-9] ) echo "You typed the digit $character" ;; # بررسی هر مورد دیگر * ) echo "You did not type a letter or a digit" esac
الگوی ویژه "
آخرین نوع کنترل جریان برنامه که ما گفتگو خواهیم نمود حلقهزنی نامیده میشود. حلقهزنی اجرای تکرار شونده یک بخش از برنامه بر اساس وضعیت خروج یک فرمان است. پوسته سه فرمان برای حلقهزنی ارایه میکند: while، until و for. ما در این درس while و until و در درس آینده for را پوشش میدهیم.
فرمان while موجب میگردد مادامیکه که وضعیت خروج فرمانِ مشخص شده صحیح باشد، یک قطعه از کد بارها و بارها اجرا گردد. این هم یک مثال ساده از یک برنامه که از صفر تا ۹ را شمارش میکند:
#!/bin/bash number=0 while [ "$number" -lt 10 ]; do echo "Number = $number" number=$((number + 1)) done
در سطر سوم، ما متغیری به نام number ایجاد کرده و مقدار صفر را به آن تخصیص میدهیم. سپس، حلقه while را شروع میکنیم. به طوریکه مشاهده میکنید، فرمانی تعیین کردهایم که مقدار number را بررسی کند. ما در مثال خود بررسی میکنیم که آیا number دارای مقداری کمتر از 10 است.
به کلمه do در سطر چهارم و کلمه done در سطر هفتم توجه کنید. اینها قطعه کدی را که میخواهیم تا زمانی که وضعیت خروج صفر باقی بماند تکرار شود محصور میکنند.
در اکثر موارد، قطعه کدی که تکرار میشود باید کاری انجام بدهد که سرانجام وضعیت خروج را تغییر خواهد داد، در غیر اینصورت با موردی مواجه میشوید که
در مثال، قطعه کد تکرار شونده مقدار number را بیرون میدهد (فرمان echo در سطر 5) و در سطر ششم number را یک واحد افزایش میدهد. هر نوبت که قطعه کد تکمیل میگردد، دوباره وضعیت خروج فرمان [ ارزیابی میشود. بعد از دهمین تکرارِ حلقه، number ده مرتبه افزایش یافته است و فرمان test با وضعیت خروج غیرصفر خاتمه مییابد. در آن نقطه، جریان برنامه با جمله بعد از کلمه done ادامه مییابد. چون done آخرین سطر مثال ما است، برنامه پایان میپذیرد.
فرمان until دقیقاً به همان روش عمل میکند، غیر از آنکه، قطعه کد تا وقتی که وضعیت خروج فرمانِ تعیین شده غلط باشد تکرار میگردد. در مثال پایین، ملاحظه کنید که چطور عبارت داده شده به فرمان test برای رسیدن به همان نتیجه نسبت به مثال while تغییر کرده است:
#!/bin/bash number=0 until [ "$number" -ge 10 ]; do echo "Number = $number" number=$((number + 1)) done
یک روش رایجِ نمایش یک واسط کاربر برای برنامههای بر پایه متن، کاربرد یک منو است. یک منو فهرستی از انتخابها است که کاربر میتواند برگزیند.
در مثال زیر، ما با استفاده از دانش جدید در مورد حلقهها و caseها برای ساختن یک برنامه ساده دارای منو استفاده میکنیم:
#!/bin/bash selection= until [ "$selection" = "0" ]; do echo " PROGRAM MENU 1 - Display free disk space 2 - Display free memory 0 - exit program " echo -n "Enter selection: " read selection echo "" case $selection in 1 ) df ;; 2 ) free ;; 0 ) exit ;; * ) echo "Please enter 1, 2, or 0" esac done
در این برنامه مقصود از حلقه until نمایش مجدد منو است، بعد از آن که یک انتخاب تکمیل گردیده باشد. حلقه تا زمانیکه انتخاب برابر "0" یعنی "exit" شود ادامه مییابد. ملاحظه کنید چگونه در برابر ورودیهای کاربر که انتخاب معتبری نیستند دفاع کردیم.
برای اینکه این برنامه موقع اجرا نمای بهتری داشته باشد، میتوانیم با افزودن یک تابع که بعد از تکمیل شدن هر انتخاب از کاربر بخواهد کلیدی را بزند، و قبل از اینکه دوباره منو نمایش داده شود صفحه نمایش را پاک کند، آن را ارتقاء بدهیم. این هم مثال ارتقاء یافته:
#!/bin/bash press_enter() { echo -en "\nPress Enter to continue" read clear } selection= until [ "$selection" = "0" ]; do echo " PROGRAM MENU 1 - display free disk space 2 - display free memory 0 - exit program " echo -n "Enter selection: " read selection echo "" case $selection in 1 ) df ; press_enter ;; 2 ) free ; press_enter ;; 0 ) exit ;; * ) echo "Please enter 1, 2, or 0"; press_enter esac done