این ساختار مورد استفاده برای انجام یک مجموعه فعالیت در صورتی که نتیجه بررسی if صحیح باشد، و مجموعه دیگر در صورت غلط بودن آن، میباشد. یک مثال:
freddy scripts>
gender
="male"
freddy scripts>
if[[ "$gender" == f* ]]
More input>
then echo"Pleasure to meet you, Madame."
More input>
else echo"How come the lady hasn't got a drink yet?"
More input>
fi How come the lady hasn't got a drink yet?freddy scripts>
[] vs. [[]] | |
---|---|
بر خلاف |
همانند CONSEQUENT-COMMANDS یعنی لیست متعاقب جمله then، لیست ALTERNATE-CONSEQUENT-COMMANDS متعاقب جمله else نیز میتواند هر دستور یونیکسی که یک کد وضعیت خروج صادرکند، را در بر داشته باشد.
یک مثال دیگر، توسعه یافته مثال بخشی به نام «بررسی وضعیت خروج»:
anny ~>
su-
Password:[root@elegance root]#
if! grep ^$USER
/etc/passwd
1>/dev/null
>
then echo"your user account is not managed locally"
>
else echo"your account is managed from the local /etc/passwd file"
>
fi your account is managed from the local /etc/passwd file[root@elegance root]#
ما برای نمایش دادن تأثیر جمله else به حساب کاربر root تغییر وضعیت دادهایم - root شما به طور معمول حساب محلی است در حالیکه حساب کاربری خودتان ممکن است توسط یک سیستم مرکزی از قبیل یک سرویس دهنده LDAP مدیریت گردد.
به جای آنکه متغیری را تنظیم کرده وسپس یک اسکریپت را اجرا کنیم، به مراتب پسندیدهتر است کمیتهای متغیرها را در خط فرمان به آن بدهیم.
ما از پارامترهای موقعیتی( یا موضعی ) $1
، $2
، ...، $N
برای این مقصود استفاده میکنیم. متغیر $#
به تعداد شناسههای خطفرمان ارجاع میدهد . متغیر $0
به نام اسکریپت ارجاع میدهد .
مثال زیر یک نمونه ساده است:
این هم یک مثال دیگر با استفاده از دو شناسه:
anny ~>
catweight.sh
#!/bin/bash # This script prints a message about your weight if you give it your # weight in kilos and height in centimeters. weight="$1" height="$2" idealweight=$[$height - 110] if [ $weight -le $idealweight ] ; then echo "You should eat a bit more fat." else echo "You should eat a bit more fruit." fianny ~>
bash-x
weight.sh
55 169
+ weight=55 + height=169 + idealweight=59 + '[' 55 -le 59 ']' + echo 'You should eat a bit more fat.' You should eat a bit more fat.
مثال زیر نشان میدهد که چگونه اسکریپت قبلی را طوری تغییر دهیم که اگر کمتر یا بیشتر از دو شناسه داده شود، یک پیغام را چاپ نماید:
anny ~>
catweight.sh
#!/bin/bash # This script prints a message about your weight if you give it your # weight in kilos and height in centimeters. if [ ! $# == 2 ]; then echo "Usage: $0 weight_in_kilos length_in_centimeters" exit fi weight="$1" height="$2" idealweight=$[$height - 110] if [ $weight -le $idealweight ] ; then echo "You should eat a bit more fat." else echo "You should eat a bit more fruit." fianny ~>
weight.sh70 150
You should eat a bit more fruit.anny ~>
weight.sh70 150 33
Usage: ./weight.sh weight_in_kilos length_in_centimeters
به اولین شناسه توسط $1
رجوع میشود، به دومی با $2
و به همین ترتیب. تعداد کل شناسهها در متغیر $#
نگهداری میشود.
بخشی به نام « کاربرد دستور exit و if » را برای روش دلپستدتر چاپ پیغامها، ملاحظه کنید.
این بررسی در تعداد زیادی از اسکریپتها انجام میشود، به علت آنکه از ابتدا در صورتی که بدانید برنامه کار نخواهد کرد، از آن استفاده نکنید:
#!/bin/bash # This script gives information about a file. FILENAME="$1" echo "Properties for $FILENAME:" if [ -f $FILENAME ]; then echo "Size is $(ls -lh $FILENAME | awk '{ print $5 }')" echo "Type is $(file $FILENAME | cut -d":" -f2 -)" echo "Inode number is $(ls -i $FILENAME | cut -d" " -f1 -)" echo "$(df -h $FILENAME | grep -v Mounted | awk '{ print "On",$1", \ which is mounted as the",$6,"partition."}')" else echo "File does not exist." fi
توجه نمایید که به فایل برای استفاده از یک متغیر رجوع شده است، در چنین حالتی آن فایل اولین شناسه اسکریپت است. به طور جایگزین، موقعی که شناسهای داده نشده است، به طور معمول محل فایلها در ابتدای یک اسکریپت ذخیره میشود، و به محتویات آن فایلها برای استفاده از این متغیرها رجوع میشود. بنابراین، موقعی که بخواهید نام یک فایل را در اسکریپت تغییر دهید، فقط یکبار آن را انجام میدهید.
فاصلهها در نام فایلها | |
---|---|
اسکریپت مثال فوق در صورتی که مقدار متغیر |
این شکل کاملی از فرمان if میباشد:
if TEST-COMMANDS; then
CONSEQUENT-COMMANDS;
elif MORE-TEST-COMMANDS; then
MORE-CONSEQUENT-COMMANDS;
else ALTERNATE-CONSEQUENT-COMMANDS;
fi
لیست TEST-COMMANDS اجرا میشود و در صورتیکه کد برگشتی صفر باشد، لیست CONSEQUENT-COMMANDS اجرا میشود. اگر TEST-COMMANDS یک کد وضعیت غیر صفر بازگرداند، هر لیست elif یکی پس از دیگری اجرا میشود، و اگر کد خروج آن صفر باشد، لیست MORE-CONSEQUENT-COMMANDS متناظر آن اجرا میشود و دستور if کامل میشود. اگر در ادامه جمله else با یک لیست ALTERNATE-CONSEQUENT-COMMANDS حضور داشته باشد، و دستور نهایی در if یا elif انتهایی منجر به یک کد خروج غیر صفر گردد، بعد ALTERNATE-CONSEQUENT-COMMANDS اجرا میشود. کد برگشتی، کد خروج آخرین دستور اجرا شده، یا اگر شرط بررسی شده صحیحی نباشد، صفر است.
این یک نمونه است که میتوانید برای اجرای روزانه در فایل crontab خودتان قرار دهید:
anny /etc/cron.daily>
catdisktest.sh
#!/bin/bash # This script does a very simple test for checking disk space. space=`df -h | awk '{print $5}' | grep % | grep -v Use | sort -n | tail -1 | cut -d "%" -f1 -` alertvalue="80" if [ "$space" -ge "$alertvalue" ]; then echo "At least one of my disks is nearly full!" | mail -s "daily diskcheck" root else echo "Disk space normal" | mail -s "daily diskcheck" root fi
در داخل دستور if، میتوانید از یک دستور if دیگر استفاده کنید. تا آنجا که به طور منطقی بتوانید اداره کنید استفاده از ifهای تو در تو در مراحل زیاد ممکن است.
این یک مثال جهت بررسی سالهای کبیسه است:
anny ~/testdir>
cattestleap.sh
#!/bin/bash # This script will test if we're in a leap year or not. year=`date +%Y` if [ $[$year % 400] -eq "0" ]; then echo "This is a leap year. February has 29 days." elif [ $[$year % 4] -eq 0 ]; then if [ $[$year % 100] -ne 0 ]; then echo "This is a leap year, February has 29 days." else echo "This is not a leap year. February has 28 days." fi else echo "This is not a leap year. February has 28 days." fianny ~/testdir>
date Tue Jan 14 20:37:55 CET 2003anny ~/testdir>
testleap.sh This is not a leap year.
مثال بالا میتواند با به کار گیری عملگرهای منطقی “AND” (&&) و “OR” (||) کوتاه شود.
ما برای بررسی یک عبارت حسابی ازپرانتزهای دوتایی استفاده کردهایم، بخشی به نام« عبارت حسابی» را ملاحظه کنید. این معادل فرمان letدر اینجا، اگر شما چیزی مشابه $[$year % 400] را بیازمایید، کروشهها را به صورت چسبیده خواهید داشت، به علت آنکه در اینجا آنها یک دستور واقعی را نمایندگی نمیکنند.
درمیان سایر ویرایشگرها، gvim یکی از آنهاست که از طرحهای رنگی مبتنی بر ساختار فایل پشتیبانی میکند، این قبیل ویرایشگرهابرای تشخیص خطاها در کدنویسی سودمند میباشند.
ما قبلاً به طور مختصر با فرمان exit در بخشی به نام«بررسی تعداد شناسهها» برخورد کردیم. این فرمان اجرای تمام اسکریپت را خاتمه میدهد. این اکثراً موقعی که ورودی درخواستی از کاربر غلط باشد، یک دستور به طور ناموفقی اجرا شود یا در صورت وقوع برخی خطاهای دیگر به کار میرود.
دستور exit یک شناسه اختیاری نیز میپذیرد. این شناسه یک عدد صحیح کد وضعیت خروج میباشد، که به والد برگردانیده میشود و در متغیر $?
ذخیره میشود.
یک شناسه صفر به این معنی است که اسکریپت به طور موفقی اجرا شده. هر مقدار دیگری میتواند توسط برنامهنویس برای بازگرداندن پیغامهای متفاوت به والد استفاده شود، به طوری که فعالیتهای متفاوتی نسبت به موفقیت یا شکست پردازش فرزند، میتواند انجام شود. اگر فرمان exit هیچ شناسهای نداشته باشد، پوسته والد مقدار جاری متغیر $?
را به کار میبرد.
در پایین یک مثال با تغییرات اندکی در اسکریپت penguin.sh
، که کد خروجش را به اسکریپت والدش، feed.sh
باز میگرداند:
anny ~/testdir>
catpenguin.sh
#!/bin/bash # This script lets you present different menus to Tux. He will only be happy # when given a fish. We've also added a dolphin and (presumably) a camel. if [ "$menu" == "fish" ]; then if [ "$animal" == "penguin" ]; then echo "Hmmmmmm fish... Tux happy!" elif [ "$animal" == "dolphin" ]; then echo "Pweetpeettreetppeterdepweet!" else echo "*prrrrrrrt*" fi else if [ "$animal" == "penguin" ]; then echo "Tux don't like that. Tux wants fish!" exit 1 elif [ "$animal" == "dolphin" ]; then echo "Pweepwishpeeterdepweet!" exit 2 else echo "Will you read this sign?!" exit 3 fi fi
این اسکریپت در سطحی بالاتر از دیگری فراخوانی شده، بنابراین متغیرهای menu
و animal
را صادر میکند:
anny ~/testdir>
catfeed.sh
#!/bin/bash # This script acts upon the exit status given by penguin.sh export menu="$1" export animal="$2" feed="/nethome/anny/testdir/penguin.sh" $feed $menu $animal case $? in 1) echo "Guard: You'd better give'm a fish, less they get violent..." ;; 2) echo "Guard: It's because of people like you that they are leaving earth all the time..." ;; 3) echo "Guard: Buy the food that the Zoo provides for the animals, you ***, how do you think we survive?" ;; *) echo "Guard: Don't forget the guide!" ;; esacanny ~/testdir>
./feed.shapple penguin
Tux don't like that. Tux wants fish! Guard: You'd better give'm a fish, less they get violent...
به طوری که میتوانید ملاحظه کنید،کدهای وضعیت خروج میتوانند آزادانه انتحاب شوند. فرمانهای موجود به طور معمول یک مجموعه از کدهای تعریف شده دارند، برای اطلاعات بیشتر مستندات برنامهنویس هر فرمان را ملاحظه کنید.