حسین کعبی: وقتی فیگو را در جام جهانی زدم....
پوسته مجموعهای از ساختارهای کنترلی دارد که بسیار به زبانهای برنامهنویسی دیگر شبیه است.
If
کاربرد عبارت if را که در شماره گذشته گفتیم و بسیار ساده است if : نتیجه یک دستور را بررسی میکند و طبق شرط گروهی از دستورات را اجرا میکند. این عبارت را ببینید:
شرط(هاIf (
Then
پاسخ شرط
else
پاسخ نبود شرط
fi
میتوان با پرسیدن سوالی از کاربر و سپس تصمیمگیری بر اساس جوابی که کاربر میدهد، مثالی سریع و کاربردی بزنیم:
َ!/bin/sh
Do you like click? Please answer”echo
“yes or no
read answer
[;then “yes”answer = $if ]
“Good Choice”echo
else
“I don't know what to say!”echo
fi
0exit
در اسکریپت بالا همه چیز روبهراه است، اما مشکلش این است که اگر چیزی جز عبارت بله یا خیر را از کاربر دریافت کند، قطعا جواب نه را اجرا خواهد کرد. این مشکل را با دستورelif که همان else if در c است را حل میکنیم. بدین صورت که، تغییر یافته کد بالا به شکل زیر در خواهد آمد:
!/bin/shَ
“Please answer yes or no ”echo
read answer
[ “yes”answer= $if ]
then
“Good Choice”echo
[; then “no”elif]$timeofday =
“Bad Choice” echo
else
answer not recognized. $Sorry, ”echo
“Enter yes or no
1 exit
fi
0exit
بسیار خب، کد بالا تا حد بسیار زیادی مشکلات را حل میکند. اما بیایید یک چیز را امتحان کنیم، کاربر اگر موقع درخواست اطلاعات، تنها کلیدreturn را بزند. در اینصورت پیغام خطای زیر نمایش داده خواهد شد:
: =: unary operator expected]
مشکل کجاست؟ خط اول دستور بررسی را نگاه کنید، وقتی که یک رشته خالی به آن پاس داده شود، به شکل زیر در خواهد آمد:
[“yes”if] =
که شرط معتبری نیست، برای جلوگیری از این اتفاق، کافیست به سراغ جادوی نقل قول برویم و متغیر را داخل نقل قول بیاندازیم:
[ “yes” = “answer$”if]
for
عبارت بعدی که بسیار بدردمان میخورد، for است. for حلقهای است که مقادیری را تا رسیدن به شرط خاصی میشمارد. ساختار کلی آن به این صورت است:
for variable in values
do
statements
done
برنامه زیر مثالی ساده است از کاربرد for که طی آن، متغیر foo مقادیر bar و fud و 43 را میگیرد.
!/bin/shَ
43for foo in bar fud
do
echo $foo
done
0exit
به این علت که تمامی متغیرهای پوسته به طور پیشفرض رشته تصور میشوند، حلقه for برای گشتن در میان مجموعهای از رشتهها ایدهآل است، اما در مواردی که مشخص نیست چند بار بایستی حلقه را تکرار کنیم، مفید به کار نمیآید.
وقتی میخواهید یک مجموعه از دستورات را اجرا کنید، اما نمیدانید که چندبار باید دستور اجرا شود، در این صورت معمولا از حلقه while استفاده میکنید که دستور آن به شکل زیر است:
while condition do
statements
done
خب، مثال زیر، مثالی ضعیف و سر دستی برای کنترل کلمه عبور است، اما در درک حلقه while کمکمان میکند:
!/bin/shَ
“Enter password” echo
read trythis
[ ; do “secret” =!“trythis$”while]
“Sorry, try again”echo
read trythis
done
0exit
دستورات بین do و done تا ابد اجرا میشوند، مگر اینکه شرط داخل براکت غلط شود.
until
عبارت until نیز این شکلی است
until condition
do
statements
done
چقدر شبیه while است، نه؟ فرقش با while این است که حلقه تا زمانی که شرط داخل براکت درست شود ادامه پیدا میکند، نه در زمانی که شرط درست است.
Case
ساختن case کمی پیچیدهتر از چیزی است که تابحال با آن مواجه شدیم. شکل کلی دستور آن اینطوری است:
case variable in
pattern] pattern [ ...) statements;;
pattern] pattern [ ...) statements;;
....
esac
در ظاهر، آدم ترس برش میدارد که این دیگر چیست، اما انصافا ببینید، با کمکcase میتوان محتویات یک متغیر با الگوهای متفاوتی مقایسه کرد و به نسبت آن الگو، دستورات متفاوتی اجرا کرد. در واقع، case وقتی به کار میآید که ما چندین و چند if, elif و else داشته باشیم.
نکته: توجه بکنید که هر الگوی case با دو نقطهویرگول (semicolon) تمام میشود. پس دو نقطهویرگول را جایی میگذاریم که یک الگو تمام میشود و الگوی بعدی قرار است شروع بشود.
قابلیت تطبیق با چندین الگو و بعد اجرا کردن چندین عبارت مرتبط با آن الگو، باعث میشود که case راه خوبی برای سر و کله زدن با ورودیهای کاربر باشد. بهترین راه برای اثبات حرفم، یک مثال است:
!/bin/shَ
Do you like Click? Please answer”echo
“yes or no
read answer
in “answer$”case
;; “Good Choice”yes) echo
;; “Bad Choice”no ) echo
;;“Good Choice”y ) echo
;;“Bad Choice”n ) echo
Sorry, answer not ” ) echo*
;;“recognized
esac
0exit
نکته: حواستان را جمع کنید، با توجه به این موضوع که درcase همیشه اولین الگوی تطبیقی تایید میشود، در این صورت وقتی از * در الگو استفاده میکنیم، باید آن را در انتها قرار دهیم. در غیر اینصورت، عبارت * همیشه انتخاب میشود، حتا اگر مثلاً الگوی بعدی دقیقتر تطبیق داده شود.
لیستها
گاهی اوقات، همه ما موقع کدنویسی، به جایی میرسیم که میخواهیم دنبالهای از شرطها برقرار باشد تا یک دستور را اجرا کنیم. یا بعضی وقتها میخواهیم حداقل یکی از شرطهای ما را برنامه داشته باشد تا فلان دستور را اجرا کنیم. در این مواقع، معمولاً از شرطهای تودرتو، یا شرطهای کنار هم استفاده میکنیم. اما، shell یک امکان جدید و نو به ما میدهد، و آنهم استفاده از لیستها است.
لیست و(and list)
لیست و، این اجازه را به برنامهنویس میدهد که دنبالهای از دستورات را اجرا کند، اگر و تنها اگر، دستورات قبل از آن صحیح و سالم اجرا شده باشند. ساختار کلی لیست و اینگونه است:
3ِِstatement2ِِstatement1Statement
در این لیست دستورات، ابتدا دستور سمت چپ اجرا میشود، اگر نتیجه آنtrue بود، سپس دستور سمت راستیاش اجرا میشود، اگر نتیجه آن نیزtrue بود، دستور سمت راستی و همینطور الی آخر. هر دستور به صورت مستقل جدا میشود و باعث میشود بتوان تعداد زیادی دستور را در یک لیست کنار هم گذاشت. لیست و تنها در صورتی موفقیت آمیز انجام میشود که تمام دستوراتش درست انجام شوند، در غیر اینصورت انجامش با شکست روبهرو میشود.
!/bin/shَ
touch file-one
rm-f file-two
ِِ“hello”if ]-f file-one[ِِecho
“there ”-f file-two[ِِecho]
then
“in if”echo
else
“in else”echo
fi
0exit
همانطور که واضح است، فایل2 را پاک کردیم و لیست موقع بررسی وجود فایل 2 مقدار false بر میگرداند و کل لیست false میشود، خر وجی این برنامه، اینطور خواهد شد:
hello
in else
لیست یا
لیست یا موقعی به کار میآید که ما میخواهیم مجموعهای از دستورات را اجرا کنیم، تا یکی بالاخره جواب درست (true) بدهد و بعد دیگر آن مجموعه از دستورات اجرا نوشت. ساختار نحوی این لیست اینطوری است:
3 statement2 statement1Statement
از سمت چپ اجرای دستورات شروع میشود، اگر نتیجه عبارت غلط بود، سپس دستور سمت راستیاش اجرا میشود. این عمل تا آنجا تکرار میشود که بالاخره یک دستور نتیجه صحیح برگرداند، که در این لحظه، دیگر هیچ عبارتی در لیست اجرا نمیشود. لیست یا خیلی شبیه به لیست و است، جز اینکه شرط اجرای دستور فعلی، غلط اجرا شدن دستور قبلی است.
!/bin/shَ
rm -f file-one
“hello”if ]-f file-one[ echo
“there ”-f file-two[ echo]
then
“in if”echo
else
“in else”echo
fi
0exit
برای تمرین، به خودتان پاسخ بدهید که چرا خروجی کد بالا، عبارت زیر میشود؟
hello
in if
محمدرضا قربانی
حسین کعبی: وقتی فیگو را در جام جهانی زدم....