نگارش جاری Bash، آن نسخهای که روی ماشین شما در حال اجراست، به احتمال بسیار نگارش 2.xx.yy، 3.xx.yy، یا 4.xx.yy است.
bash$ echo $BASH_VERSION 3.2.25(1)-release
در به روزرسانی نگارش 2 زبان اسکریپتنویسی Bash کلاسیک، متغیرهای آرایهای، بسط رشته و پارامتر، و یک شیوه مناسبتری از ارجاعات غیر مستقم متغیر در میان ویژگیهای دیگر اضافه گردید.
#!/bin/bash #بسط رشته. #معرفی شده در Bashنگارش 2 #رشتههایی به شکل $'xxx' دارای کاراکترهای #+استاندارد escape شده تفسیر گردیدند. echo $'Ringing bell 3 times \a \a \a' #با برخی ترمینالها ممکن است فقط یکبار زنگ بزند. #یا ... #بسته به تنظیمات ترمینال ممکن است زنگ نزند. echo $'Three form feeds \f \f \f' echo $'10 newlines \n\n\n\n\n\n\n\n\n\n' echo $'\102\141\163\150' # #معادل اکتال کاراکترها. exit
مثال 37-2- ارجاعات غیر مستقیم متغیر - روش جدید
#!/bin/bash #ارجاع غیر مستقیم متغیر. #این دارای مقداری از خصوصیات ارجاعها در C++ است. a=letter_of_alphabet letter_of_alphabet=z echo "a = $a" #ارجاع مستقیم. echo "Now a = ${!a}" #ارجاع غیر مستقیم. #نشانهگذاری ${!variable} قابل درکتر از نشانهگذاری #+قدیمی eval var1=\$$var2 است. echo t=table_cell_3 table_cell_3=24 echo "t = ${!t}" # table_cell_3=387 echo "Value of t changed to ${!t}" # #eval لازم نیست. #این برای مراجعه به عناصر یک آرایه یا جدول، یا #+برای شبیهسازی یک آرایه چند بعدی مفید است. #یک گزینه شاخصگذاری (متشابه با اشارهگرهای حسابی) #+چقدر خوب میشد. افسوس. exit 0 #مثال ind-ref.sh را نیز ببینید.
مثال 37-3. کاربرد ساده بانک اطلاعاتی، با استفاده از ارجاع متغیر غیر مستقیم
#!/bin/bash # #کاربرد ساده بانک داده / مراجعه به جدول. #============================================================== # #دادهها B1723_value=470 #Ohms B1723_powerdissip=.25 #Watts B1723_colorcode="yellow-violet-brown" #Color bands B1723_loc=173 #Where they are B1723_inventory=78 #How many B1724_value=1000 B1724_powerdissip=.25 B1724_colorcode="brown-black-red" B1724_loc=24N B1724_inventory=243 B1725_value=10000 B1725_powerdissip=.125 B1725_colorcode="brown-black-orange" B1725_loc=24N B1725_inventory=89 #============================================================== # echo PS3='Enter catalog number: ' echo select catalog_number in "B1723" "B1724" "B1725" do Inv=${catalog_number}_inventory Val=${catalog_number}_value Pdissip=${catalog_number}_powerdissip Loc=${catalog_number}_loc Ccode=${catalog_number}_colorcode echo echo "Catalog number $catalog_number:" #اکنون، بازیابی کمیتها، با استفاده از ارجاع غیر مستقیم. echo "There are ${!Inv} of [${!Val} ohm / ${!Pdissip} watt]\ resistors in stock." # #از Bash نگارش 4.2، شما میتوانید "ohm" را با #\u2126 تعویض کنید (با استفاده از echo -e). #echo "These are located in bin # ${!Loc}." echo "Their color code is \"${!Ccode}\"." break done echo; echo # مترجم: فرمان echo -e $'\u2126' نماد Ω را نمایش میدهد تمرینها: #------------------------ #(1 این اسکریپت را برای خواندن دادههایش از یک فایل بازنویسی کنید. #(2 این اسکریپت را برای استفاده از آرایهها به جای ارجاع غیر مستقیم #+متغیر بازنویسی نمایید. #کدام روش روانتر و به طور مستقیم قابل درک است؟ #کد نویسی برای کدام روش آسانتر است؟ #یادداشتها: #------------------------ #اسکریپتهای پوسته برای هر کاری غیر از سادهترین کاربردهای بانک داده #+نامناسب هستند، و حتی آنوقت هم درگیر راهحلهای موقت میشوند. #بسیار بهتر است از زبانی با پشتیبانی ذاتی از ساختارهای داده، مانند #+C++ یا جاوا (یا حتی پرل) exit 0برای کار با دادهها استفاده گردد.
مثال 37-4. استفاده از آرایهها و ترفندهای متفرقه دیگر برای توزیع تصادفی یک دست ورق بین ۴ نفر
#!/bin/bash # #توزیع تصادفی یک دست ورق بین چهار نفر. UNPICKED=0 PICKED=1 DUPE_CARD=99 LOWER_LIMIT=0 UPPER_LIMIT=51 CARDS_IN_SUIT=13 CARDS=52 declare -a Deck declare -a Suits declare -a Cards #پیادهسازی آن با یک آرایه منفرد سه بعدی، آسانتر وقابل درکتر خواهد بود. #شاید یک نگارش آینده از Bash آرایههای چند بعدی را پشتیبانی کند. initialize_Deck () { i=$LOWER_LIMIT until [ "$i" -gt $UPPER_LIMIT ] do Deck[i]=$UNPICKED #تنظیم همه کارتهای دسته ورق به عنوان انتخاب نشده. let "i += 1" done echo } initialize_Suits () { Suits[0]=C #Clubs Suits[1]=D #Diamonds Suits[2]=H #Hearts Suits[3]=S #Spades } initialize_Cards () { Cards=(2 3 4 5 6 7 8 9 10 J Q K A) #روشی از مقدار دهی یک آرایه. } pick_a_card () { card_number=$RANDOM let "card_number %= $CARDS" #منحصر کردن محدوده به 0 - 51، یعنی 52 کارت. if [ "${Deck[card_number]}" -eq $UNPICKED ] then Deck[card_number]=$PICKED return $card_number else return $DUPE_CARD fi } parse_card () { number=$1 let "suit_number = number / CARDS_IN_SUIT" suit=${Suits[suit_number]} echo -n "$suit-" let "card_no = number % CARDS_IN_SUIT" Card=${Cards[card_no]} printf %-4s $Card #چاپ کارتها در ستونهای مرتب. } seed_random () #بذر تولید کننده اعداد تصادفی. { #اگر این کار را نکنید چه میشود؟ seed=`eval date +%s` let "seed %= 32766" RANDOM=$seed } #سایر روشهای بذر پاشی تولید کننده عدد تصادفی را بررسی کنید. deal_cards () { echo cards_picked=0 while [ "$cards_picked" -le $UPPER_LIMIT ] do pick_a_card t=$? if [ "$t" -ne $DUPE_CARD ] then parse_card $t u=$cards_picked+1 #موقتا،برگرداندن شاخصگذاری به مبنای شروع از یک. چرا؟ let "u %= $CARDS_IN_SUIT" if [ "$u" -eq 0 ] #تست شرطی if/then تو در تو. then echo echo fi #هر دسته با یک سطر خالی کنار گذاشته میشود. let "cards_picked += 1" fi done echo return 0 } #برنامهنویسی ساختیافته: #منطق کل برنامه در توابع پیمانهای شده. #=============== seed_random initialize_Deck initialize_Suits initialize_Cards deal_cards #=============== exit #تمرین 1: #توضیحاتی برای مستند کردن تمام این اسکریپت اضافه کنید. #تمرین 2: #یک روال (تابع) اضافه کنید که خالهای هر نفر جور شده چاپ شود. #شما میتوانید سایر نوآوریهایی را که دوست دارید اضافه نمایید. #تمرین 3: #منطق اسکریپت را سادهسازی کرده و کارایی آن را افزایش بدهید.