4. بلوکهای شرطی( if و test و [[ )
$if true >then echo "It was true." >else echo "It was false." >fi It was true.
در اینجا یک نمای کلی اساسی از
افراد مختلف شیوههای متفاوتی از نوشتن جملات
if commandsthen other commandsfi -------------------if commandsthen other commandsfi -------------------if commands; then other commandsfi
چند دستور وجود دارد که به طور ویژه برای بررسی موارد و بازگرداندن وضعیت خروج نسبت به آنچه تشخیص میدهند، طراحی گردیدهاند. اولین دستور از این قبیل test میباشد( که [ نیز شناخته میشود.) یک نگارش پیشرفتهتر آن
$if [ a= b ] >then echo "a is the same as b." >else echo "a is not the same as b." >fi a is not the same as b.
حال ببینیم که چرا
$myname = \'Greg Wooledge\' yourname= \'Someone Else\' $ [$ myname = $ yourname ]-bash: [: too many arguments
میتوانید حدس بزنید چه مشکلی موجب بروز خطا شده؟
دستور [ با شناسههای
$ ["$ myname " = "$ yourname " ]
در این حالت [ دومین شناسه را یک عملگر(
برای کمی مساعدت با ما، پوسته Korn یک سبک جدید بررسی شرطی را معرفی نموده(و BASH نیز آن را اخذ کرده). مؤلف اصل اینها که
یکی از ویژگیهای
$[[ $ filename = * .png]] && echo "$ filename looks like a PNG file"
ویژگی دیگر
$[[ $ me = $ you ]] # Fine. $[[ I am$ me = I am$ you ]] # Not fine!-bash: conditional binary operator expected -bash: syntax error near `am\'
در این حالت، نیازی به نقلقولی کردن
$[[ "I am$ me "= "I am$ you "]]
همچنین، تفاوت ظریف زیرکانهای بین نقلقولی کردن و نکردن سمت راست مقایسه در
$foo = [a-z]*name = lhunath $[[ $ name = $ foo ]] && echo "Name$ name matches pattern$ foo "Name lhunath matches pattern [a-z]* $[[ $ name = "$ foo "]] || echo "Name$ name is not equal to the string$ foo "Name lhunath is not equal to the string [a-z]*
بررسی اول کنترل میکند که آیا
یادآوری: همواره اگر اطمینان ندارید نقلقولی کنید. اگر
میتوانید چندین دستور
$name = lhunath $if [[ $ name = "George"]] >then echo "Bonjour,$ name " >elif [[ $ name = "Hans"]] >then echo "Goeie dag,$ name " >elif [[ $ name = "Jack"]] >then echo "Good day,$ name " >else > echo "You\'re not George, Hans or Jack. Who the hell are you,$ name ?" >fi
حال که درک مناسبی از مسائلی که با نقلقولها ممکن است ایجاد شود به دست آوردهاید، بیایید به سایر ویژگیهایی که [ و
بررسیهایی که با [ ( که به عنوان test نیزشناخته میشود) پشتیبانی میشود:
-e FILE: اگر فایل موجود باشد صحیح است.
-f FILE: اگر فایل موجود معمولی باشد صحیح است.
-d FILE: اگر فایل یک دایرکتوری باشد صحیح است.
-h FILE: اگر فایل یک پیوند نمادین باشد صحیح است.
-r FILE: اگر فایل برای شما قابل خواندن باشد صحیح است.
-s FILE: اگر فایل موجود باشد وتهی نباشد صحیح است.
-t FD : اگر FD(توصیفگر فایل) در یک ترمینال باز شده باشد صحیح است.
-w FILE: اگر فایل برای شما قابل نوشتن باشد صحیح است.
-x FILE: اگر فایل برای شما قابل اجرا باشد صحیح است.
-O FILE: اگر فایل به طور مؤثر در مالکیت شما باشد صحیح است.
-G FILE: اگر فایل به طور مؤثر در مالکیت گروه شما باشد صحیح است.
FILE -nt FILE: اگر فایل اول جدیدتر از فایل دوم باشد صحیح است.
FILE -ot FILE: اگر فایل اول قدیمیتر از فایل دوم باشد صحیح است.
-z STRING: اگر رشته تهی باشد(طول آن صفر باشد) صحیح است.
-n STRING: اگر رشته تهی نباشد(طول آن صفر نباشد) صحیح است.
STRING = STRING: اگر رشته اول از هر نظر مانند دومی باشد صحیح است.
STRING != STRING: اگر رشته اول دقیقاً مانند رشته دوم نباشد صحیح است.
STRING < STRING:اگر در مرتبسازی رشته اول قبل از دومی قرار میگیرد صحیح است.
STRING > STRING: اگر رشته اول در مرتبسازی بعد از رشته دوم قرارمیگیرد صحیح است.
EXPR -a EXPR: اگر هر دوعبارت صحیح باشندصحیح است(and منطقی).
EXPR -o EXPR: اگر هر یک از دو عبارت صحیح باشد صحیح است(or منطقی).
! EXPR: نتیجه عبارت را معکوس میکند( NOTمنطقی).
INT -eq INT: اگر هر دو عدد صحیح دقیقاً برابر باشند صحیح است.
INT -ne INT: اگر هر دو عدد صحیح دقیقاً برابر نباشند، صحیح است.
INT -lt INT: اگر عدد صحیح اولی کوچکتر از دومی باشد صحیح است.
INT -gt INT: اگر عدد صحیح اولی از دومی بزرگتر باشد صحیح است.
INT -le INT: اگر عدد صحیح اولی کوچکتر یا مساوی دومی باشد صحیح است.
INT -ge INT: اگر عدد صحیح اولی بزرگتر یا مساوی دومی باشد صحیح است.
بررسیهای اضافی که فقط توسط
[[ پشتیبانی میشوند :STRING = (or ==) PATTERN: مانند [ (یا test) مقایسه نمیکند، بلکه انطباق الگو انجام میشود. اگر رشته با الگوی جانشین منطبق گردد، صحیح است.
STRING =~ REGEX: اگر رشته با الگوی regex(عبارت منظم)تطبیق کند، صحیح است.
( EXPR ): پرانتزها میتوانند برای تغییر اولویت ارزیابیها به کار بروند.
EXPR && EXPR: خیلی مشابه عملگر
-a در test میباشد، اما اگر نتیجه عبارت اول صحیح نباشد، عبارت دوم ارزیابی نمیشود.EXPR || EXPR: خیلی مشابه عملگر
-o در test میباشد، اما اگر نتیجه عبارت اول صحیح باشد، عبارت دوم ارزیابی نمیشود.
چند مثال؟ حتماً:
$ test-e /etc/X11/xorg.conf&& echo \'Your Xorg is configured!\'Your Xorg is configured! $ test-n "$ HOME "&& echo \'Your homedir is set!\'Your homedir is set! $[[ boar!= bear]] && echo "Boars aren\'t bears."Boars aren\'t bears! $[[ boar!= b? ar]] && echo "Boars don\'t look like bears." $ $[[ $ DISPLAY ]] && echo "Your DISPLAY variable is not empty, you probably have Xorg running."Your DISPLAY variable is not empty, you probably have Xorg running. $[[ ! $ DISPLAY ]] && echo "Your DISPLAY variable is not not empty, you probably don\'t have Xorg running." $
-
تکرارمفید:
هنگامی که یک اسکریپت BASH ایجاد میکنید، همیشه باید از[[ به جای [ استفاده کنید.
وقتی یک اسکریپت پوسته مینویسید، که پس از اتمام ممکن است در محیطی که BASH در دسترس نباشد، به کار برود، باید از [ استفاده کنید، به دلیل آنکه به مراتب قابل حملتر میباشد. ( در حالیکه در BASH و برخی پوستههای دیگر، [ یک دستور داخلی است، به صورت یک برنامه خارجی نیز به خوبی در دسترس میباشد، یعنی به عنوان شناسه مثلاً exec و xargs کار خواهد کرد.)
هرگز از -a یا -o در بررسیهای فرمان [ استفاده نکنید. به جای آن از فرمانهای چندگانه [ ( یا اگر میتوانید از[[ ) استفاده کنید. استاندارد POSIX رفتار [ در مجموعه بررسیهای پیچیده را تعریف نکرده، بنابراین هرگز نمیدانید چه رفتاری حاصل میشود.if [ "$ food "= apple ]&& [ "$ drink "= tea ]; then echo "The meal is acceptable."fi
-
در مستندات گنو: Conditional Constructs
-
در پرسش و پاسخهای رایج:
-
چگونه میتوانم عبارتها را گروهبندی کنم، مثل (a
AND b)OR c؟ -
چطور میتوانم تعیین نمایم که آیا یک متغیر شامل یک زیر رشته هست؟
چگونه میتوانم بگویم که یک متغیر آیا محتوی یک عدد معتبر هست؟
-
if (کلمهکلیدی): لیستی از دستورات را اجرا میکند و سپس نسبت به کد خروج آنها، کد بلوکthen ( بخش اختیاریelse ) را اجرا مینماید.