Bash مفهوم مقادیر منطقی را ندارد. رشته و عدد داریم، و آرایههایی از رشته یا عدد. پس دستورهای شرطی چگونه با «درست» و «غلط» برخورد میکنند؟
دستورها وقتی به پایان میرسند یک «وضعیت خروج» تولید میکنند. وضعیت خروج یک عدد صحیح بین ۰ و ۲۵۵ است (شامل هر دو سر). Bash وضعیت خروج صفر را نشانهی موفقیت میداند. هر وضعیت خروج دیگری نشانهی شکست است.
این موضوع دربارهی همهی دستورها صادق است، از جمله دستورهای توکار bash، کلیدواژهها و توابع.
if
نحوهی نگارش پایهی دستور if چنین است
if CONDITIONAL_COMMANDS; then TRUE_COMMANDS; else FALSE_COMMANDS; fi
با if شروع میشود؛ دستورهای شرط با then از دستورهای «موفقیت» جدا میشوند؛ و با fi پایان مییابد.
بند else اختیاری است.
CONDITIONAL_COMMANDS میتواند یک دستور تنها باشد یا یک فهرست از دستورها.
CONDITIONAL_COMMANDS اجرا میشوند و
شاخههای آبشاری را میتوان با elif نوشت
if CONDITIONAL_COMMANDS
then TRUE_COMMANDS
elif CONDITIONAL_COMMANDS_2
then TRUE_COMMANDS_2
# more elif branches ...
else FALSE_COMMANDS
fi
پیش از واژههای then، elif، else و fi باید یک نقطهویرگول یا یک خط جدید باشد.
برای تأکید: این وضعیت خروج دستورهای شرطی است که جریان برنامه را کنترل میکند.
برای مثال، grep اگر تطابقی پیدا شود ۰ برمیگرداند و اگر تطابقی پیدا نشود ۱.
گزینهی -q خروجی را سرکوب میکند و تنها وضعیت خروج را تولید میکند.
if grep -q "my pattern" my_file; then echo "the pattern is found in the file"; fi
[ و test
هیچ نحوهی نگارش ویژهای پیرامون CONDITIONAL_COMMANDS وجود ندارد. ممکن است به دیدن دستورهای شرطی به این شکل عادت داشته باشید:
if [ "$password" = "secure" ]; then
echo "Welcome!"
fi
[ نحوهی نگارش ویژهای نیست.
یک دستور است که عبارت شرطی را ارزیابی میکند و با وضعیت موفقیت یا شکست خارج میشود.
مانند همهی دستورها، بین آن و آرگومانهایش فاصله ضروری است.
[ در واقع مترادف دستور test است.
این دو دقیقاً یکساناند، جز اینکه آخرین آرگومان [ باید ] باشد.
درون [ و ] یک عبارت شرطی مینویسید.
از جمله عبارتهای شرطی معمول میتوان به اینها اشاره کرد:
[ -f "$filename" ] # file operations
[ "$string1" = "$string2" ] # string comparisons
[ "$num1" -eq "$num2" ] # arithmetic comparisons
عملیاتهای بسیار بیشتری هم موجود است؛ آنها در بخش عبارتهای شرطی Bash از راهنما فهرست شدهاند.
در مثالهای بالا توجه کنید که همهی متغیرها داخل نقلقول آمدهاند.
دستورهای test و [ دستورهایی معمولیاند که آرگومانهایشان، مانند هر دستور دیگری، در معرض تقسیم واژه و بسط نام فایل قرار دارند.
اشاره به این نکته مهم است چون عبارتهای شرطی بسته به تعداد آرگومانهایی که میدهید متفاوت ارزیابی میشوند:
[ -z "$name" ])، یا یک ! (که وضعیت آزمون تکآرگومانی را نفی میکند)اگر نقلقول را فراموش کنید ممکن است به نتایج غیرمنتظره برسید:
str=""
# this prints "empty"
if [ -n "$str" ]; then echo "not empty"; else echo "empty"; fi
# leaving the variable unquoted results in incorrect "not empty" output
if [ -n $str ]; then echo "not empty"; else echo "empty"; fi
[[
ساختار شرطی [[...]] یک دستور نیست، بلکه یک کلیدواژه است.
این یعنی هرچند مانند هر دستور دیگری پردازش میشود، قواعد تجزیهی ویژهای دارد.
ویژگی خاص [[ این است که متغیرهایی که درونش بسط داده میشوند در معرض تقسیم واژه یا بسط نام فایل نیستند.
یعنی این دستور، حتی بدون نقلقول، همانطور که انتظار دارید عمل میکند.
if [[ -n $str ]]; then echo "not empty"; else echo "empty"; fi
[[ از همهی عبارتهای شرطی که test و [ میتوانند پردازش کنند پشتیبانی میکند.
علاوه بر این، [[ این موارد را فراهم میکند
=~،== و != که بهعنوان عملگر تطبیق با الگوی glob عمل میکنند،&& و || بهعنوان عملگرهای منطقی (با قاعدهی تجزیهی ویژه)،< و > بهعنوان عملگرهای مقایسهی رشتهی بدون نقلقول (قاعدهی تجزیهی ویژه: چون اینها نمادهای تغییر مسیر هستند، در [ باید اسکیپ شوند).دیدگاه رایجی است که این ویژگیهای خاص آنقدر سودمندند که باید منحصراً از [[ استفاده کرد.
(برای مثال، راهنمای سبکنگارش Shell گوگل.)
case
case یکی دیگر از دستورهای کنترل جریان است.
مانند دستور switch در زبانهای دیگر است.
case WORD in [PATTERN [| PATTERN]...) COMMANDS ;;]... esac
WORD با هر PATTERN تطبیق داده میشود. وقتی یکی تطبیق پیدا کند، COMMANDS اجرا میشوند.
read -p "Guess the secret word: " word
case "$word" in
secret) echo "Yes, you guessed it!" ;;
??????) echo "That's the right number of letters." ;;
s*) echo "You guessed the first letter." ;;
*) echo "Not even close! Try again." ;;
esac
هر بند COMMANDS باید با دو نقطهویرگول، ;;، پایان یابد.
۱. جایگزینهایی وجود دارند که امکان اجرای پشتسرهم دستورها و ادامهی تطبیق الگو را فراهم میکنند. برای جزئیات راهنما را ببینید. ۲. به یاد بیاورید که دربارهی الگوها در بخش بسط نام فایل از مفهوم Quoting صحبت کردیم.