ساختارهای
کنترل جریان برنامه در یک قطعه کد
ساختار case در اسکریپتنویسی پوسته قابل قیاس با switch در C/C++ است. این ساختار بر اساس وضعیت بررسیها، انشعاب به یکی از چند قطعه کد را اجازه میدهد. به عنوان یک نوع میانبر برای چندین جمله
case "$variable" in
"$condition1" )
command...
;;
"$condition2" )
command...
;;
esac
|
#!/bin/bash # echo; echo "Hit a key, then hit return." read Keypress case "$Keypress" in [[:lower:]] ) echo "Lowercase letter";; [[:upper:]] ) echo "Uppercase letter";; [0-9] ) echo "Digit";; * ) echo "Punctuation, whitespace, or other";; esac #محدوده کاراکترها در [براکتها]، یا محدودههای #+POSIX در [[ براکتهای دوتایی را اجازه میدهد. # #+[a-z] و [A-Z] بود. این دیگر در برخی مناطق و/یا توزیعهای لینوکس #کار نمیکند. POSIX بیشتر قابل حمل است. #با نشکر از Frank Wang برای اشاره نمودن به این مورد. # # # # #+کلید گزارش بدهد، و فقط وقتی "X" زده میشود، خاتمه یابد. #اشاره: همه چیز را درون یک حلقه "while" قرار بدهید. exit 0
مثال 11-26. ایجاد منوها با استفاده از case
#!/bin/bash # clear # echo " Contact List" echo " ------- ----" echo "Choose one of the following persons:" echo echo "[E]vans, Roland" echo "[J]ones, Mildred" echo "[S]mith, Julie" echo "[Z]ane, Morris" echo read person case "$person" in # "E" | "e" ) # echo echo "Roland Evans" echo "4321 Flash Dr." echo "Hardscrabble, CO 80753" echo "(303) 734-9874" echo "(303) 734-9892 fax" echo "revans@zzy.net" echo "Business partner & old friend" ;; # "J" | "j" ) echo echo "Mildred Jones" echo "249 E. 7th St., Apt. 19" echo "New York, NY 10009" echo "(212) 533-2814" echo "(212) 533-9972 fax" echo "milliej@loisaida.com" echo "Ex-girlfriend" echo "Birthday: Feb. 11" ;; #بعداً اطلاعات Smith و Zane را اضافه کنید. * ) # # echo echo "Not yet in database." ;; esac echo # # # #+ exit 0
یک استفاده هوشمندانه استثنایی case به بررسی پارامترهای سطر فرمان مربوط میشود.
#! /bin/bash case "$1" in "") echo "Usage: ${0##*/} <filename>"; exit $E_PARAM;; # #توجه کنید که ${0##*/} جایگزینی پارامتر ${var##pattern} است. #نتیجه خالص $0 است. -*) FILENAME=./$1;; #اگر نام فایل داده شده به عنوان ($1) با یک خط تیره شروع شود، آن #+را با ./$1 تعویض کند طوری که فرمانها دیگر آن را به عنوان #+ * ) FILENAME=$1;; #در غیر اینصورت، $1 باشد. esac
این هم یک مثال قابل فهمتر در مورد مدیریت پارامتر خط فرمان:
#! /bin/bash while [ $# -gt 0 ]; do # case "$1" in -d|--debug) #پارامتر "-d" یا "--debug" است؟ DEBUG=1 ;; -c|--conf) CONFFILE="$2" shift if [ ! -f $CONFFILE ]; then echo "Error: Supplied file doesn't exist!" exit $E_CONFFILE # fi ;; esac shift # done #از اسکریپت "Log2Rot" بسته "rottlog" متعلق به Stefano Falsetto #
مثال 11-27. کاربرد جایگزینی فرمان برای تولید متغیر case
#!/bin/bash #case-cmd.sh: استفاده از جایگزینی فرمان در تولید یک متغیر "case". case $( arch ) in #$( arch ) معماری کامپیوتر را برگشت میدهد. #معادل با 'uname -m' i386 ) echo "80386-based machine";; i486 ) echo "80486-based machine";; i586 ) echo "Pentium-based machine";; i686 ) echo "Pentium2+-based machine";; * ) echo "Other type of machine";; esac exit 0
یک ساختار case میتواند رشتهها را بواسطه الگوهای globbing فیلتر کند.
مثال 11-28. انطباق رشته ساده
#!/bin/bash #match-string.sh: انطباق رشته ساده #کاربرد یک ساختار 'case'. match_string () { # Exact string match. MATCH=0 E_NOMATCH=90 PARAMS=2 # E_BAD_PARAMS=91 [ $# -eq $PARAMS ] || return $E_BAD_PARAMS case "$1" in "$2") return $MATCH;; * ) return $E_NOMATCH;; esac } a=one b=two c=three d=two match_string $a # echo $? # match_string $a $b # echo $? # match_string $b $d # echo $? # exit 0
مثال 11-29. کنترل برای ورودی الفبایی
#!/bin/bash #isalpha.sh: کاربرد ساختار "case" برای فیلتر کردن یک رشته. SUCCESS=0 FAILURE=1 #FAILURE=-1 بود اما Bash دیگر برگشت #+ isalpha () # { if [ -z "$1" ] #آیا شناسهای ارایه نشده است؟ then return $FAILURE fi case "$1" in [a-zA-Z]*) return $SUCCESS;; #با یک حرف شروع میشود؟ * ) return $FAILURE;; esac } #این را با تابع "isalpha ()" در C مقایسه کنید. isalpha2 () #بررسی میکند آیا «تمام رشته» الفبایی است. { [ $# -eq 1 ] || return $FAILURE case $1 in *[!a-zA-Z]*|"") return $FAILURE;; *) return $SUCCESS;; esac } isdigit () #بررسی می کند آیا «تمام رشته» عددی است. { #به بیان دیگر، برای متغیر صحیح بررسی میکند. [ $# -eq 1 ] || return $FAILURE case $1 in *[!0-9]*|"") return $FAILURE;; *) return $SUCCESS;; esac } check_var () #وابسته به تابع isalpha () { if isalpha "$@" then echo "\"$*\" begins with an alpha character." if isalpha2 "$@" then #اگر کاراکتر اول الفبایی نباشد، این بررسی لزومی ندارد. echo "\"$*\" contains only alpha characters." else echo "\"$*\" contains at least one non-alpha character." fi else echo "\"$*\" begins with a non-alpha character." #همچنین اگر شناسهای داده نشده باشد، غیر الفبایی است. fi echo } digit_check () #وابسته به تابع isdigit () { if isdigit "$@" then echo "\"$*\" contains only digits [0 - 9]." else echo "\"$*\" has at least one non-digit character." fi echo } a=23skidoo b=H3llo c=-What? d=What? e=$(echo $b) #جایگزینی فرمان. f=AbcDef g=27234 h=27a34 i=27.34 check_var $a check_var $b check_var $c check_var $d check_var $e check_var $f check_var #شناسهای داده نشده، بنابراین چه میشود؟ # digit_check $g digit_check $h digit_check $i exit 0 #اسکریپت توسط S.C. بهینه شده است. # # #یک تابع isfloat () بنویسید که اعداد اعشاری را بررسی کند. #اشاره: تابع رونوشت isdigit () است اما یک تست برای بررسی #+نقطه اعشار اختیاری اضافه میشود.
ساختار
selectvariable [in list]
do
command...
break
done
این ساختار، برای وارد کردن یکی از انتخابهای نمایش داده شده در variable list اعلانی به کاربر ارایه میدهد. توجه کنید که select به طور پیشفرض اعلان $PS3 (#?) را به کار میبرد، اما این اعلان میتواند تغییر داده شود.
مثال 11-30. تولید منوها با استفاده از select
#!/bin/bash PS3='Choose your favorite vegetable: ' # #در غیر اینصورت پیشفرض #? echo select vegetable in "beans" "carrots" "potatoes" "onions" "rutabagas" do echo echo "Your favorite veggie is $vegetable." echo "Yuck!" echo break #اگر در اینجا 'break' نباشد چه اتفاقی رخ میدهد؟ done exit # # # #+تعیین نشده در جمله "select" اصلاح کنید. #برای مثال، اگر کاربر "peas" را وارد نماید، اسکریپت #+پاسخ بدهد "Sorry. That is not on the menu."
اگر in list ذکر نگردد، آنوقت select لیست شناسههای سطر فرمان ($@) عبور داده شده به اسکریپت یا تابع محتوی ساختار select را به کار میبرد.
این مورد را با رفتار ساختار for variable [in list] که in list در آن از قلم افتاده، مقایسه کنید.
مثال 11-31. تولید منوها با استفاده از select در یک تابع
#!/bin/bash PS3='Choose your favorite vegetable: ' echo choice_of() { select vegetable #[in list] ذکر نشده، پس 'select' شناسههای داده شده به تابع را استفاده میکند. do echo echo "Your favorite veggie is $vegetable." echo "Yuck!" echo break done } choice_of beans rice carrots radishes rutabaga spinach # #تحویل داده شده به تابع choice_of() exit 0
همچنین مثال 37-3 را ببینید.
[1] |
برای چیدمانی با ظاهر شکیلتر، سطرهای انطباق الگو میتوانند با یک پرانتز سمت چپ -( - نیز شروع بشوند. case $( arch ) in # |