آرایه یک متغیر محتوی چندین کمیت میباشد. هر متغیری میتواند به عنوان یک آرایه استفاده شود. برای حداکثر اندازه آرایه محدودیتی وجود ندارد، هیچ احتیاجی هم نیست که متغیرهای عضو شاخصگذاری بشوند یا به طور متوالی تخصیص داده شوند. آرایهها zero-based هستند: اولین عنصر با صفر شاخص میخورد.
تعریف غیر مستقیم با استفاده از ترکیب دستوری زیر برای تعریف یک متغیر انجام میشود:
ARRAY[INDEXNR]
=value
INDEXNR به عنوان یک عبارت حسابی تلقی میگردد که باید با یک عدد مثبت سنجیده شود.
تعریف صریح یک آرایه با استفاده از فرمان داخلی declare انجام میشود:
declare
-a
ARRAYNAME
تعریف با یک عدد شاخص نیز پذیرفته میشود، اما عدد شاخص صرفنظر خواهد شد. صفتها برای آرایه میتواند با استفاده از فرمانهای داخلی declare و readonly تعیین بشود. صفتها به تمام متغیرهای آرایه اعمال میگردند، نمیتوانید آرایههای مختلط داشته باشید.
متغیرهای آرایه همچنین ممکن است با استفاده از اختصاص مرکب، به این شکل:
ARRAY
=(value1 value2 ... valueN)
ایجاد گردند، و بعد هر کمیت به شکل [indexnumber=]string میباشد. عدد شاخص اختیاری است، اگر این عدد ذکر شود به متغیر نسبت داده میشود و در غیر آنصورت. شاخص عضو انتصابی عدد آخرین شاخص تخصیص یافته به اضافه یک است. این قالب به خوبی توسط declare پذیرفته میشود. اگر هیچ عدد شاخصی ذکر نشده باشد، شاخصگذاری از صفر شروع میشود.
اضافهنمودن عضو غایب یا اعضاء اضافه به یک آرایه با به کار بردن این ترکیب دستوری انجام میشود:
ARRAYNAME[indexnumber]
=value
به خاطر داشته باشید که فرمان داخلی read گزینه -a
را فراهم میکند، که خواندن وتخصیص کمیتهای اعضاء یک آرایه را اجازه میدهد.
به منظور رجوع به محتوای یکی از اقلام یک آرایه، به طور معمول از ابروها( آکولادها ) استفاده میشود. به طوری که در مثال زیر میبینید، این مورد برای کنار گذاشتن تفسیر پوسته بسط عملگرها ضروری است. اگر عدد شاخص @ یا * باشد، همه اعضاء آرایه مورد رجوع هستند.
[bob in ~]
ARRAY
=(one two three)
[bob in ~]
echo${ARRAY[*]}
one two three[bob in ~]
echo$ARRAY[*]
one[*][bob in ~]
echo${ARRAY[2]}
three[bob in ~]
ARRAY[3]
=four
[bob in ~]
echo${ARRAY[*]}
one two three four
ارجاع به محتوی یک متغیر عضو آرایه بدون ذکر شماره شاخص همانند ارجاع به اولین عضواست، ارجاع به عضوی که شماره شاخص آن صفر است.
دستور داخلی unset برای تخریب یک آرایه یامتغیرهای یک آرایه به کار میرود:
[bob in ~]
unsetARRAY[1]
[bob in ~]
echo${ARRAY[*]}
one three four[bob in ~]
unsetARRAY
[bob in ~]
echo${ARRAY[*]}
<--no output-->
مثالهای عملی کاربرد آرایهها مشکل یافت میشود. مثالهای فراوانی از اسکریپتهایی که به طور واقعی کاری روی سیستم انجام نمیدهند، امااز آرایهها به عنوان نمونه، برای یک سری محاسبات ریاضی استفاده میکنند، را پیدا خواهید نمود. و آنها از جالبترین مثالها خواهند بود...اکثر اسکریپتهافقط به یک روش فوق ساده شده و نظری نشان میدهند که با آرایه چه میتوانید انجام دهید.
دلیل این کمبود پیچیدگی بیشتر ساختارهای آرایهای میباشد. شما خواهید دید که اکثر مثالهای عملی که آرایهها در آنها میتوانند به کار روندقبلاً در سیستم شما پیادهسازی شدهاند، اگر چه در سطح پایینتر، در زبان برنامهنویسی C که اکثر فرمانهای یونیکس در آن زبان نوشته شدهاند. یک مثال خوب فرمان داخلی history در Bash میباشد. خوانندگانی که علاقمند هستند میتوانند دایرکتوری built-ins
در منابع Bash را بررسی کرده و به fc.def
که موقع کامپایل built-ins پردازش میشود، نگاه کنند.
دلیل دیگر اینکه مثالهای خوب مشکل پیدا میشوند، آنست که همه پوستهها از آرایهها پشتیبانی نمیکنند، بنابراین آن اسکریپتها سازگاری را نقض میکنند.
پس از روزهای طولانی جستجو، در نهایت این مثال عملیاتی را در یک فراهم کننده اینترنتی یافتم. توزیع کننده فایلهای پیکربندی سرویسدهنده شبکه Apache روی میزبانها در یک اجارهدهنده است :
#!/bin/bash if [ $(whoami) != 'root' ]; then echo "Must be root to run $0" exit 1; fi if [ -z $1 ]; then echo "Usage: $0 </path/to/httpd.conf>" exit 1 fi httpd_conf_new=$1 httpd_conf_path="/usr/local/apache/conf" login=htuser farm_hosts=(web03 web04 web05 web06 web07) for i in ${farm_hosts[@]}; do su $login -c "scp $httpd_conf_new ${i}:${httpd_conf_path}" su $login -c "ssh $i sudo /usr/local/apache/bin/apachectl graceful" done exit 0
اول دو بررسی برای اینکه آیا کاربر مجاز اسکریپت را با شناسههای صحیح اجرا میکند، انجام میشود. بعد نام میزبانهایی که لازم است پیکربندی بشوند در آرایه farm_hosts
لیست میشوند. سپس تمام این میزبانها، پس از آنکه daemon راهاندازی مجدد شد، بافایل پیکربندی Apache تهیه میگردند. به کاربرد فرمانهای برنامه پوسته امن( Secure Shell ) توجه نمایید، رمزنگاری ارتباطات با میزبانهای راهدور.
تشکر از Eugene و همکارش برای این مساعدت.
Dan Richter درمثال زیر همکاری نمود این مشکلی است که او با آن مواجه شده بود:
«...در شرکت من، ما نمایشهایی در پایگاه اینترنتی خودمان داشتیم، و هر هفته باید شخصی همه آنها را بررسی میکرد. برای همین من یک cron job داشتم که یک آرایه را از اسامی داوطلبان احتمالی پر میکرد، از فرمان date +%W
برای پیدا کردن شماره هفته سال استفاده کرده، و عملیاتی برای پیدا کردن یک شماره شاخص درست انجام میداد. شخص خوشاقبال به وسیله پست الکترونیک مطلع میشد.»
و روش او برای حل کردن آن چنین بود:
#!/bin/bash # This is get-tester-address.sh # # First, we test whether bash supports arrays. # (Support for arrays was only added recently.) # whotest[0]='test' || (echo 'Failure: arrays not supported in this version of bash.' && exit 2) # # Our list of candidates. (Feel free to add or # remove candidates.) # wholist=( 'Bob Smith <bob@example.com>' 'Jane L. Williams <jane@example.com>' 'Eric S. Raymond <esr@example.com>' 'Larry Wall <wall@example.com>' 'Linus Torvalds <linus@example.com>' ) # # Count the number of possible testers. # (Loop until we find an empty string.) # count=0 while [ "x${wholist[count]}" != "x" ] do count=$(( $count + 1 )) done # # Now we calculate whose turn it is. # week=`date '+%W'` # The week of the year (0..53). week=${week#0} # Remove possible leading zero. let "index = $week % $count" # week modulo count = the lucky person email=${wholist[index]} # Get the lucky person's e-mail address. echo $email # Output the person's e-mail address.
این اسکریپت بعد در سایر اسکریپتها، از قبیل این یکی که ازیک here document استفاده میکند، به کار میرود:
email=`get-tester-address.sh` # Find who to e-mail. hostname=`hostname` # This machine's name. # # Send e-mail to the right person. # mail $email -s '[Demo Testing]' <<EOF The lucky tester this week is: $email Reminder: the list of demos is here: http://web.example.com:8080/DemoSites (This e-mail was generated by $0 on ${hostname}.) EOF