هر builtin یک فرمان گنجانده شده در داخل مجموعه ابزار Bash است، به طور لفظی built in (توکار). این یا به دلایل افزایش کارایی است -- builtinها سریعتر از فرمانهای خارجی، که معمولاً به انشعاب [1] یک پردازش جداگانه نیاز دارند، اجرا میگردند -- یا به علت آنکه یک builtin خاص نیازمند دسترسی مستقیم به داخلیهای پوسته است.
موقعی که یک فرمان یا خود پوسته پردازش فرعی جدیدی را برای انجام دادن یک وظیفه آغاز میکند (یا تولید مثل میکند)، این کار انشعاب نامیده میشود. این پردازش جدید، فرزند، و پردازشی که آن را منشعب کرده است پدر یا والد است. در حالیکه پردازش فرزند کارش را انجام میدهد، پردازش پدر هنوز در حال اجرا میباشد. توجه داشته باشید، در حالیکه یک پردازش پدر ID پردازش فرزند را دریافت میکند، و به این طریق میتواند شناسهها را به آن عبور بدهد، بر عکس آن صادق نیست. این مورد میتواند سبب بروز مشکلاتی گردد که پیگیری آنها دشوار و پیچیده است. مثال 15-1. اسکریپتی که چندین نمونه خودش را تولید مثل میکند #!/bin/bash # PIDS=$(pidof sh $0) # عموماً، در Bash وقتی یک builtin در اسکریپت اجرا میگردد، پردازش فرعی منشعب نمیکند. در اسکریپتها معمولاً یک فرمان خارجی سیستم یا فیلتر، یک پردازش فرعی منشعب خواهد نمود. |
یک builtin ممکن است مترادفی برای یک فرمان سیستم با همان نام باشد، که Bash دوباره آن را به طور درونی پیادهسازی نموده. برای مثال، فرمان echo در Bash همان /bin/echo نیست، اگرچه رفتار آنها تقریباً یکسان است.
#!/bin/bash echo "This line uses the \"echo\" builtin." /bin/echo "This line uses the /bin/echo system command."
یک کلمهکلیدی، یک واژه، نشانه، یا عملگری ذخیره شده است. کلمهکلیدیها برای پوسته دارای معنای ویژهای هستند، و در واقع بلوکهای ساختمان گرامر پوسته هستند. به عنوان مثال،
یک عبارت یا متغیر را (در stdout) چاپ میکند ( مثال 4-1 را ببینید).
echo Hello echo $a
echo برای چاپ کاراکترهای escape شده، به یک گزینه -e احتیاج دارد. مثال 5-2 را ببینید.
به طور عادی، هر فرمان echo یک سطر جدید ترمینال چاپ میکند، اماگزینه -n مانع این کار میگردد.
یک echo میتواند برای تغذیه رشته به فرمانها در یک لوله به کار برود.
if echo "$VAR" | grep -q txt # then echo "$VAR contains the substring sequence \"txt\"" fi |
یک echo در تلفیق با جایگزینی فرمان میتواند یک متغیر را تنظیم کند.
a=`echo "HELLO" | tr A-Z a-z` همچنین مثال 16-22، مثال 16-3، مثال 16-47، و مثال 16-48 را ببینید. |
آگاه باشید که echo `command` هر سطرجدیدی را که خروجی command تولید نماید، حذف میکند.
متغیر $IFS(جداکننده داخلی فیلد) به طور معمول شامل \n (تعویض سطر) به عنوان یکی از کاراکترهای مجموعه فضای سفیدش میباشد. بنابراین Bash خروجی command را از محل تعویض سطرها به شناسههایی برای echo تجزیه میکند. آنوقت echo این شناسهها را به صورت جدا شده با یک فاصله بیرون میدهد.
bash$ ls -l /usr/share/apps/kjezz/sounds total 40 -rw-r--r-- 1 root root 1407 Nov 7 2000 reflect.au -rw-r--r-- 1 root root 362 Nov 7 2000 seconds.au bash$ echo `ls -l /usr/share/apps/kjezz/sounds` total 40 -rw-r--r-- 1 root root 716 Nov 7 2000 reflect.au -rw-r--r-- 1 root root ...
بنابراین، چگونه میتوانیم یک سطرجدید را داخل یک رشته کاراکتر echo شده، جاسازی نماییم؟
#جاسازی یک linefeed؟ echo "Why doesn't this string \n split on two lines?" # # echo echo $"A line of text containing a linefeed." #به صورت دو سطر جدا(با linefeed جاسازی شده) چاپ میگردد. #اما، آیا واقعاً پیشوند متغیر "$" لازم است؟ echo echo "This string splits on two lines." #خیر، به پیشوند "$" نیازی نیست. echo echo "---------------" echo echo -n $"Another line of text containing a linefeed." #به عنوان دو سطر مجزا (با linefeed جاسازی شده) چاپ میگردد. #حتی گزینه -n در اینجا در خنثی کردن تعویض سطر ناموفق است. echo echo echo "---------------" echo echo # #چرا عمل نمیکند؟ اشاره: تخصیص به یک متغیر. string1=$"Yet another line of text containing a linefeed (maybe)." echo $string1 # # # #با تشکر از Steve Parker برای توضیح این مورد.
این فرمان یک builtin پوسته است، و همان /bin/echo نیست، هرچند که رفتارش همانند آن است.
bash$ type -a echo echo is a shell builtin echo is /bin/echo |
فرمان printf، چاپ قالبدار، یک echo ارتقاء یافته است. این فرمان نوع محدود شدهای از تابع کتابخانهای printf() زبان C است، و ترکیب دستوری آن تا اندازهای متفاوت است.
printf format-string ... parameter...
این نگارش builtin پوسته Bash از فرمان /bin/printf یا /usr/bin/printf است. برای پوشش عمیقتر صفحه man (فرمانِ سیستم) printf را ببینید.
نگارشهای قدیمیتر Bash ممکن است از printf پشتیبانی نکنند. |
#!/bin/bash #نمونهنمایشی عملیات printf declare -r PI=3.14159265358979 # declare -r DecimalConstant=31373 Message1="Greetings," Message2="Earthling." echo printf "Pi to 2 decimal places = %1.2f" $PI echo printf "Pi to 9 decimal places = %1.9f" $PI # printf "\n" #یک سطرجدید چاپ میکند، معادل 'echo' است. printf "Constant = \t%d\n" $DecimalConstant #یک tab (\t) درج میکند. printf "%s %s \n" $Message1 $Message2 echo # #شبیهسازی تابع sprintf() زبان C # echo Pi12=$(printf "%1.12f" $PI) echo "Pi to 12 decimal places = $Pi12" # Msg=`printf "%s %s \n" $Message1 $Message2` echo $Msg; echo $Msg #اتفاقاً تابع sprintf اکنون میتواند به عنوان یک پیمانه (module) #+قابل بارگیری به Bash اضافه گردد، اما قابل حمل نیست. exit 0
قالببندی پیغام خطاها، یک کاربرد مفید printf است.
E_BADDIR=85 var=nonexistent_directory error() { printf "$@" >&2 #پارامترهای مکانی داده شده را قالببندی و به sterr ارسال مینماید. echo exit $E_BADDIR } cd $var || error $"Can't cd to %s." "$var" #با تشکر از S.C.
همچنین مثال 36-17 را ببینید.
مقدار یک متغیر را از stdin «میخواند»، یعنی ورودی را به طور محاورهای از صفحهکلید اخذ میکند. گزینه -a اجازه میدهد فرمان read متغیرهای آرایهای دریافت کند ( مثال 27-6 را ببینید).
مثال 15-3. تخصیص متغیر، با استفاده از read
#!/bin/bash # echo -n "Enter the value of variable 'var1': " #گزینه -n با echo، سطرجدید را موقوف میکند. read var1 #علامت $ در جلوی var1 نیست، چون متغیر در حال تنظیم شدن است. echo "var1 = $var1" echo #یک جمله واحد read میتواند چند متغیر را تنظیم نماید. echo -n "Enter the values of variables 'var2' and 'var3' " echo =n "(separated by a space or tab): " read var2 var3 echo "var2 = $var2 var3 = $var3" #اگر فقط یک مقدار وارد کنید، سایر متغیرها تنظیم نشده (null) باقی خواهند ماند. exit 0
یک read بدون یک متغیر مرتبط شده، ورودیاش را به متغیر اختصاصی $REPLY تخصیص میدهد.
مثال 15-4. آنچه هنگام فقدان متغیرِ فرمان read روی میدهد
#!/bin/bash # read-novar.sh echo # echo -n "Enter a value: " read var echo "\"var\" = "$var"" # # echo # echo -n "Enter another value: " read #متغیری برای read فراهم نگردیده است، بنابراین... #+ورودی برای read به متغیر پیشفرض $REPLY تخصیص یافته. var="$REPLY" echo "\"var\" = "$var"" # # echo echo "=========================" echo #این مثال مشابه اسکریپت «reply.sh» است. #اگر چه، آن اسکریپت نشان میدهد که حتی بعد از یک read #+مطابق معمول همراه با یک متغیر، $REPLY در دسترس است. # # #در چنین حالتهایی، به سادگی متغیر $REPLY را صرفنظر کنید. { # read # read line2 # } <$0 echo "Line 2 of this script is:" echo "$line2" # echo #سطر #!/bin/bash رها گردیده است. #اسکریپت soundcard-on.sh را نیز ملاحظه کنید. exit 0
به طور عادی، وارد کردن یک \ در جریان ورودی برای یک read، سطر جدید را خنثی میکند. گزینه -r باعث میشود \ وارد شده، به طور لفظی تفسیر گردد.
مثال 15-5. ورودی چند سطری برای read
#!/bin/bash echo echo "Enter a string terminated by a \\, then press <ENTER>." echo "Then, enter a second string (no \\ this time), and again press <ENTER>." read var1 #"\" موقع خواندن $var1 سطر جدید را موقوف میکند. # # echo "var1 = $var1" # #برای هر سطر خاتمه یافته به وسیله یک \ شما یک اعلان روی سطر #+بعدی جهت ادامه تغذیه کاراکترها به var1 دریافت میکنید. echo; echo echo "Enter another string terminated by a \\ , then press <ENTER>." read -r var2 #گزینه -r باعث میشود \ به طور لفظی خوانده شود. # echo "var2 = $var2" # #ورود دادهها با اولین <ENTER> خاتمه مییابد. echo exit 0
فرمان read دارای تعدادی گزینه جالب است که نمایش یک اعلان و حتی خواندن ضربهکلیدها بدون زدن ENTER را مجاز میکنند.
#خواندن یک ضربه کلید بدون زدن ENTER. read -s -n1 -p "Hit a key " keypress echo; echo "Keypress was "\"$keypress\""." #گزینه -s یعنی ورودی را منعکس نکند. #گزینه -n یا -N یعنی فقط N کاراکتر از ورودی قبول کند. #گزینه -p یعنی قبل از خواندن ورودی اعلان پس از آن را نمایش بدهد. #کاربرد این گزینهها، مهارتآمیز است، چون لازم است که آنها به ترتیب صحیح باشند.
گزینه -n برای read همچنین تشخیص کلیدهای جهتی و برخی از سایر کلیدهای غیرعادی را میسر میکند.
مثال 15-6. تشخیص کلیدهای جهتنما
#!/bin/bash # #با تشکر از Sandro Magi، برای نشان دادن چگونگی آن به من. # # arrowup='\[A' arrowdown='\[B' arrowrt='\[C' arrowleft='\[D' insert='\[2' delete='\[3' # SUCCESS=0 OTHER=65 echo -n "Press a key... " #اگر کلیدی که در بالا لیست نشده، فشرده شود، ممکن است زدن ENTER نیز لازم باشد. read -n3 key # echo -n "$key" | grep "$arrowup" # if [ "$?" -eq $SUCCESS ] then echo "Up-arrow key pressed." exit $SUCCESS fi echo -n "$key" | grep "$arrowdown" if [ "$?" -eq $SUCCESS ] then echo "Down-arrow key pressed." exit $SUCCESS fi echo -n "$key" | grep "$arrowrt" if [ "$?" -eq $SUCCESS ] then echo "Right-arrow key pressed." exit $SUCCESS fi echo -n "$key" | grep "$arrowleft" if [ "$?" -eq $SUCCESS ] then echo "Left-arrow key pressed." exit $SUCCESS fi echo -n "$key" | grep "$insert" if [ "$?" -eq $SUCCESS ] then echo "\"Insert\" key pressed." exit $SUCCESS fi echo -n "$key" | grep "$delete" if [ "$?" -eq $SUCCESS ] then echo "\"Delete\" key pressed." exit $SUCCESS fi echo " Some other key pressed." exit $OTHER # #Mark Alexander یک نگارش ساده شده از #+ #نیاز به استفاده از grep را برطرف میکند. #!/bin/bash uparrow=$'\x1b[A' downarrow=$'\x1b[B' leftarrow=$'\x1b[D' rightarrow=$'\x1b[C' read -s -n3 -p "Hit an arrow key: " x case "$x" in $uparrow) echo "You pressed up-arrow" ;; $downarrow) echo "You pressed down-arrow" ;; $leftarrow) echo "You pressed left-arrow" ;; $rightarrow) echo "You pressed right-arrow" ;; esac exit $? # #Antonio Macchi یک پیشنهاد سادهتر دارد. #!/bin/bash while true do read -sn1 a test "$a" == `echo -en "\e"` || continue read -sn1 a test "$a" == "[" || continue read -sn1 a case "$a" in A) echo "up";; B) echo "down";; C) echo "right";; D) echo "left";; esac done # # # #(1 تشخیص کلیدهای Home، End، PgUp، و PgDn را اضافه کنید. #مترجم: گرچه بعید است، اما اگر پس از تلاش کافی پاسخ را ندانستید، این را بینید.
گزینه -n با فرمان read کلید ENTER (سطر جدید) را آشکار نخواهد نمود. |
گزینه -t با فرمان read زمانبندی ورودی را ممکن میسازد (مثال 9-4 و مثال A-41 را ببینید).
گزینه -u توصیفگرفایل برای فایل مقصد را قبول میکند.
فرمان read همچنین میتواند مقدار متغیرش را از یک فایل تغییر مسیر یافته به stdin «بخواند». اگر فایل محتوی بیش از یک سطر باشد، تنها سطر اول به متغیر تخصیص داده میشود. اگر read دارای بیش از یک پارامتر باشد، آنوقت به هر یک از این پارامترها یک رشته متعاقب فضای سفید مشخصشده تخصیص داده میشود. توجه کنید!
مثال 15-7. استفاده از read با تغییر مسیر فایل
#!/bin/bash read var1 <data-file echo "var1 = $var1" #var1 به تمام سطر نخست فایل ورودی «data-file» تنظیم میگردد. read var2 var3 <data-file echo "var2 = $var2 var3 = $var3" #به رفتار ظاهرا نامفهوم read در اینجا توجه نمایید. #(1 به ابتدای فایل ورودی باز میگردد. #(2 اکنون هر متغیری به جای تمام سطر، به یک رشته متناظر جدا شده #با فضای سفید تنظیم میشود. #(3 متغیر انتهایی باقیمانده سطر را دریافت میکند. #(4 اگر تعداد متغیرها بیش از رشتههای جدا شده با فضای سفید در #سطر اول باشد، آنوقت متغیرهای اضافی تهی باقی میمانند. echo "------------------------------------------------" #چگونگی رفع اشکال فوق با یک حلقه: while read line do echo "$line" done <data-file #با تشکر از Heiner Steven برای توضیح این مورد. echo "------------------------------------------------" #جهت تجزیه سطر ورودی برای فرمان read، در صورتیکه نمیخواهید فضایسفید #پیشفرض باشد، از $IFS (جداکنندهفیلد داخلی) استفاده نمایید. echo "List of all users:" OIFS=$IFS; IFS=: #فایل /etc/passwd از جداکنندهفیلد : استقاده میکند. while read name passwd uid gid fullname ignore do echo "$name ($fullname)" done </etc/passwd # IFS=$OIFS #بازیابی $IFS اولیه. #این خُرده کد نیز توسط Heiner Steven است. #تنظیم متغیر $IFS در داخل خود حلقه نیاز به ذخیره #+$IFS اصلی در یک متغیر موقتی را برطرف میکند. #با تشکر از Dim Segebart برای توضیح دادن این مورد. echo "------------------------------------------------" echo "List of all users:" while IFS=: read name passwd uid gid fullname ignore do echo "$name ($fullname)" done </etc/passwd # echo echo "\$IFS still $IFS" exit 0
لولهکشی خروجی به یک فرمان read، با استفاده از echo برای تنظیم متغیرها، ناموفق خواهد شد. با این وجود، به نظر میرسد لوله کشی خروجی cat کار میکند.
cat file1 file2 | while read line do echo $line done با این حال، به طوریکه Bjön Eriksson نشان میدهد: مثال 15-8. مشکلات خواندن از یک لوله #!/bin/sh # # اسکریپت gendiff، که معمولاً روی اکثر توزیعهای لینوکس در /usr/bin یافت میشود، خروجی find را به یک ساختار while read لولهکشی میکند. find $1 \( -name "*$2" -o -name ".*$2" \) -print | while read f; do . . . |
paste کردن متن به داخل فیلد ورودی یک read امکانپذیر است (اما نه سطرهای چندتایی!). مثال A-38 را ببینید. |
فرمان آشنای تعویض دایرکتوری cd، در جایی از اسکریپتها مورد استفاده مییابد که اجرای یک فرمان نیازمند قرار داشتن در یک دایرکتوری معین است.
(cd /source/directory && tar cf - . ) | (cd /dest/directory && tar xpvf -)[از مثال قبلاً ذکر شده Alan Cox]
گزینه -P (physical) نزد cd باعث صرفنظر کردن این فرمان از پیوندهای نمادین میگردد.
cd - به $OLDPWD، یعنی دایرکتوری کاری قبلی تغییر مکان میدهد.
فرمان cd موقع حضور دو کاراکتر // بعد از آن، آنطور که انتظار میرود عمل نمیکند. bash$ cd // bash$ pwd //البته خروجی باید / باشد. این مشکل هم در خط فرمان و هم در داخل اسکریپت وجود دارد. |
چاپ دایرکتوری کاری (Print Working Directory). این فرمان دایرکتوری جاری کاربر (یا اسکریپت) را ارایه میکند ( مثال 15-9 را ببینید). اثر آن معادل خواندن مقدار متغیر درونی $PWD است.
این مجموعه فرمان، ساز و کاری برای نشانکگذاری دایرکتوریهای کاری، وسیلهای برای حرکت به طرف عقب و جلو در میان دایرکتوریها است. برای پیگردی نام دایرکتوریها، از یک پشته پایین فشردنی استفاده میشود. گزینههایی دستکاریهای گوناگون پشته دایرکتوری را میسر میسازند.
pushd dir-name مسیر dir-name را در درون پشته دایرکتوری جای میدهد (در بالای پشته) و به طور همزمان دایرکتوری کاری جاری را به dir-name تغییر میدهد.
popd نام مسیر دایرکتوری در بالای پشته دایرکتوری را حذف نموده و به طور همزمان دایرکتوری کاری جاری را به دایرکتوری دیگری که اکنون در بالای پشته قرار گرفته، تغییر میدهد.
dirs محتویات پشته دایرکتوری را لیست میکند (این را با متغیر $DIRSTACK قیاس نمایید). یک فرمان موفق pushd یا popd به طور خودکار فرمان dirs را فراخوانی میکند.
اسکریپتهایی که نیازمند چندین تغییر دایرکتوری کاری هستند، میتوانند بدون درج تغییرات نام دایرکتوری در اسکریپت به خوبی از این فرمانها استفاده کنند. توجه داشته باشید که متغیر آرایهای ضمنی $DIRSTACK قابل دسترس در داخل اسکریپت، محتویات پشته دایرکتوری را نگهداری میکند.
مثال 15-9. تغییر دایرکتوری کاری جاری
#!/bin/bash dir1=/usr/local dir2=/var/spool pushd $dir1 #یک dirs هم اجرا خواهد نمود (لیست کردن پشته دایرکتوری در خروجی استاندارد). echo "Now in directory `pwd`." #از 'pwd' پوشش یافته با نقلقول برعکس استفاده میکند. #اکنون، مواردی را در دایرکتوری dir1 انجام بدهید. pushd $dir2 echo "Now in directory `pwd`." #حالا، کارهایی در دایرکتوری dir2 انجام بدهید. echo "The top entry in the DIRSTACK array is $DIRSTACK." popd echo "Now back in directory `pwd`." #اینک، کارهای دیگری در دایرکتوری dir1 انجام بدهید. popd echo "Now back in original working directory `pwd`." exit 0 #چه اتفاقی رخ میدهد اگر popd نکنید، سپس اسکریپت خارج شود؟ #سرانجام در کدام دایرکتوری هستید؟ چرا؟
فرمان let عملیات حسابی بر روی متغیرها را انجام میدهد. [3] در موارد بسیاری، مانند یک نگارش کمتر پیچیدهِ expr عمل میکند.
مثال 15-10. انجام عملیات حساب توسط let.
#!/bin/bash echo let a=11 #همانند با a=11 let a=a+5 #معادل با let "a = a + 5" # echo "11 + 5 = $a" # let "a <<= 3" #معادل با let "a = a << 3" echo "\"\$a\" (=16) left-shifted 3 places = $a" # let "a /= 4" #معادل با let "a = a / 4" echo "128 / 4 = $a" # let "a -= 5" #معادل با let "a = a - 5" echo "32 - 5 = $a" # let "a *= 10" #معادل با "a = a * 10" echo "27 * 10 = $a" # let "a %= 8" #معادل با let "a = a % 8" echo "270 modulo 8 = $a (270 / 8 = 33, remainder $a)" # #آیا let عملیات سبکِ C را اجازه میدهد؟ بله، درست مانند #ساختار پرانتزهای دوتایی (( ... )) اجازه میدهد. let a++ # echo "6++ = $a" # let a-- # echo "7-- = $a" # #البته، ++a، و غیره نیز اجازه داده میشوند. echo #عملگر سهگانه. #توجه نمایید که $a برابر با 6 است، بالا را مشاهده کنید. let "t = a<7?7:11" # echo $t # let a++ let "t = a<7?7:11" # echo $t # exit
فرمان let در برخی مضمونها میتواند یک وضعیت خروج شگفتآور برگشت بدهد.
# |
eval arg1 [arg2] ... [argN]
شناسههای داخل یک عبارت یا لیست عبارتها را ترکیب کرده و آنها را ارزیابی میکند. همه متغیرهای داخل عبارت بسط داده میشوند. نتیجه اصلی، تبدیل شدن یک رشته به یک فرمان است.
bash$ command_string="ps ax" bash$ process="ps ax" bash$ eval "$command_string" | grep "$process" 26973 pts/3 R+ 0:00 grep --color ps ax 26974 pts/3 R+ 0:00 ps ax
هر فراخوانی eval یک ارزیابی مجدد شناسههایش را تحمیل میکند.
a='$b' b='$c' c=d echo $a # # eval echo $a # # eval eval echo $a # # #با تشکر از E. Choroba
#!/bin/bash #به کار گیری "eval" ... y=`eval ls -l` #مشابه با y=`ls -l` است، اما چون متغیر «echo» شده echo $y #+غیرنقلقولی است، تعویض سطرها حذف میشوند. echo echo "$y" #وقتی متغیر نقلقولی شود، تعویض سطرها حفظ میگردند. echo; echo y=`eval df` #مشابه با y=`df` echo $y #+اما تعویض سطرها حذف شدهاند. #وقتی LFها حفظ نشدهاند، ممکن است تجزیه خروجی با استفاده #+از برنامههای سودمندی از قبیل awk آسانتر باشد. echo echo "===========================================================" echo eval "`seq 3 | sed -e 's/.*/echo var&=ABCDEFGHIJ/'`" # # # echo echo "===========================================================" echo #اکنون، نشان دادن چگونگی انجام کار سودمند با eval . . . #(با تشکر از E. Choroba!) version=3.4 # #+ echo "version = $version" eval major=${version/./;minor=} #. در شماره نگارش را با ;minor= تعویض میکند #در اثر جایگزینی 3; minor=4 حاصل میشود #+پس eval روی minor=4, major=3 عمل میکند. echo Major: $major, minor: $minor #
مثال 15-12. کاربرد eval برای انتخاب از میان متغیرها
#!/bin/bash # # #+ arr0=( 10 11 12 13 14 15 ) arr1=( 20 21 22 23 24 25 ) arr2=( 30 31 32 33 34 35 ) #0 1 2 3 4 5 شماره عضو (شاخصگذاری از صفر) choose_array () { eval array_member=\${arr${array_number}[element_number]} # #کاربرد eval برای ساختن نام یک متغیر، در #+ echo "Element $element_number of array $array_number is $array_member" } # array_number=0 # element_number=3 choose_array # array_number=2 # element_number=4 choose_array # array_number=3 #آرایه تهی (arr3 تخصیص نیافته است). element_number=4 choose_array # #با تشکر از Antonio Macchi برای توضیح این مورد.
مثال 15-13. Echo کردن پارامترهای خط فرمان
#!/bin/bash # # # # params=$# # param=1 # while [ "$param" -le "$params" ] do echo -n "Command-line parameter " echo -n \$$param #فقط «نام» متغیرها را ارایه میکند. ## # #\$ اولین $ را معاف (eacape)میکند، پس به طور لفظی بازتاب مییابد #+و $param همانطور که انتظار میرود به محتوای $param بسط مییابد. echo -n " = " eval echo \$$param # # #eval بر «ارزیابی» \$$ به عنوان #+ (( param ++ )) # done exit $? #bash$ sh echo-params.sh first second third fourth fifth Command-line parameter $1 = first Command-line parameter $2 = second Command-line parameter $3 = third Command-line parameter $4 = fourth Command-line parameter $5 = fifth
مثال 15-14. اجبار به یک log-off
#!/bin/bash #کشتن ppp برای تحمیل یک log-off اجباری. #البته برای ارتباط dialup # SERPORT=ttyS3 # #+میتواند متفاوت باشد، و /dev/ttyS1 یا /dev/ttyS2 باشد. killppp="eval kill -9 `ps ax | awk '/ppp/ { print $1 }'`" #-------- ID پردازش ppp ------- $killppp # # chmod 666 /dev/$SERPORT #بازیابی مجوزهای r+w یا مورد دیگری؟ #چون انجام یک SIGKILL بر ppp مجوزهای درگاه سریال را تغییر میدهد، #+ rm /var/lock/LCK..$SERPORT # exit $? # # #(1 وادار نمودن اسکریپت به کنترل آنکه آیا کاربر ارشد آنرا احضار میکند. #(2 قبل از اقدام به کشتن پردازش، کنترلی انجام بدهید تا پردازشی که باید #+کشته شود واقعاً در حال اجرا باشد. #(3 یک نگارش جایگزین برای این اسکریپت بر اساس fuser بنویسید: #+
مثال 15-15. یک نگارش از rot13 [۱]
#!/bin/bash #نگارشی از rot13 با استفاده از eval. #با مثال rot13.sh مقایسه کنید. setvar_rot_13() # { local varname=$1 varvalue=$2 eval $varname='$(echo "$varvalue" | tr a-z n-za-m)' } setvar_rot_13 var "foobar" #تخصیص foobar از طریق rot13 echo $var # setvar_rot_13 var "$var" #تخصیص sbbone از طریق rot13 # echo $var # #مثال نوشته Stephane Chazelas است که توسط نگارنده ویرایش گردیده. exit 0
این هم یک مثال دیگر از کاربرد eval برای ارزیابی یک عبارت پیچیده، این مثال از یک نگارش قدیمیتر اسکریپت بازی Tetris نوشته YongYe است.
eval ${1}+=\"${x} ${y} \"
مثال A-53 از eval برای تبدیل عناصر آرایه به یک لیست فرمان استفاده میکند.
فرمان eval در روش قدیمیتر ارجاع غیرمستقیم دیده میشود.
eval var=\$$var
فرمان eval میتواند برای پارامتردار کردن بسط ابرو به کار برود. |
فرمان eval میتواند دارای خطر باشد، و به طور معمول موقعی که یک جایگزین معقول وجود دارد باید از آن پرهیز نمود. یک eval $COMMANDS محتویات COMMANDS را اجرا میکند، که ممکن است شامل موارد ناگوار حیرتانگیزی از قبیل rm -rf * باشد. اجرای یک eval روی کُد ناشناس نوشته شده توسط افراد ناشناخته، رفتاری مخاطرهآمیز است. |
فرمان set مقدار متغیرها/گزینههای داخلی اسکریپت را تغییر میدهد. یک مورد استفاده آن برای تغییر وضعیت گزینه نشانگرهایی است که به تعیین رفتار اسکریپت کمک میکنند. یک کاربرد دیگر برای آن، بازنشاندن پارامترهای مکانی که یک اسکریپت به عنوان نتیجه یک فرمان مشاهده میکند (set `command`). آنوقت اسکریپت میتواند فیلدهای خروجی فرمان را تجزیه کند.
مثال 15-16. استفاده از set با پارامترهای مکانی
#!/bin/bash # # # #به عنوان مثال به صورت، "sh ex34.sh one two three". echo echo "Positional parameters before set \`uname -a\` :" echo "Command-line argument #1 = $1" echo "Command-line argument #2 = $2" echo "Command-line argument #3 = $3" set `uname -a` #پارامترهای مکانی را با خروجی فرمان `uname -a` تنظیم میکند echo echo +++++ echo $_ # # echo $- # # echo echo "Positional parameters after set \`uname -a\` :" #$1، $2، $3، و غیره با نتیجه فرمان `uname -a` مقداردهی شدهاند. echo "Field #1 of 'uname -a' = $1" echo "Field #2 of 'uname -a' = $2" echo "Field #3 of 'uname -a' = $3" echo \#\#\# echo $_ # echo exit 0
تفنن بیشتر با پارامترهای مکانی.
مثال 15-17. وارونه کردن پارامترهای مکانی
#!/bin/bash # #اسکریپت توسط Dan Jacobson، با بازبینی از نظر سبک توسط نگارنده این سند. set a\ b c d\ e; # # OIFS=$IFS; IFS=:; # echo until [ $# -eq 0 ] do # echo "### k0 = "$k"" # k=$1:$k; # # echo "### k = "$k"" # echo shift; done set $k # echo - echo $# # echo - echo for i #حذف «in list» متغیر i را با پارامترهای مکانی تنظیم میکند. do echo $i # done IFS=$OIFS #بازیابی IFS # # #+جداکننده داخلی فیلد IFS به یک مقدار جدید لازم است؟ #اگر اینکار را نکنید چه اتفاقی رخ میدهد؟ امتحان کنید. #و چرا در سطر 17 برای درج کردن در متغیر حلقه، IFS جدید #+(یک کولن)به کار میرود؟ هدف از به کار بردن آن چیست؟ exit 0
$ ./revposparams.sh ### k0 = ### k = a b ### k0 = a b ### k = c a b ### k0 = c a b ### k = d e c a b - 3 - d e c a b
فراخوانی set بدون یک گزینه یا شناسه، فقط تمام متغیرهای محیطی و سایر متغیرهای ارزشگذاری شده را لیست میکند.
bash$ set AUTHORCOPY=/home/bozo/posts BASH=/bin/bash BASH_VERSION=$'2.05.8(1)-release' ... XAUTHORITY=/home/bozo/.Xauthority _=/etc/bashrc variable22=abc variable23=xzy
کاربرد set با گزینه -- به طور صریح محتویات یک متغیر را به پارامترهای مکانی تنظیم میکند. اگر متغیری گزینه -- را دنبال نکند، این فرمان پارامترهای مکانی را unset میکند.
مثال 15-18. تخصیص مجدد پارامترهای مکانی
#!/bin/bash variable="one two three four five" set -- $variable #پارامترهای مکانی را با محتویات "$variable" تنظیم میکند. first_param=$1 second_param=$2 shift; shift # #shift 2 نیز کار میکند. remaining_params="$*" echo echo "first parameter = $first_param" # echo "second parameter = $second_param" # echo "remaining parameters = $remaining_params" # echo; echo # set -- $variable first_param=$1 second_param=$2 echo "first parameter = $first_param" # echo "second parameter = $second_param" # # set -- #اگر متغیری تعیین نشده باشد پارامترهای مکانی را Unset میکند. first_param=$1 second_param=$2 echo "first parameter = $first_param" # echo "second parameter = $second_param" # exit 0
همچنین مثال 11-2 و مثال 16-56 را ببینید.
فرمان unset یک متغیر پوسته را حذف میکند، به طور ثمربخش آن را به null تنظیم میکند. توجه نمایید که این فرمان بر پارامترهای مکانی اثر نمیکند.
bash$ unset PATH bash$ echo $PATH bash$
مثال 15-19. "unset" کردن یک متغیر
#!/bin/bash # variable=hello # echo "variable = $variable" unset variable #unset متغیر، در این مضمون خاص #+دارای همان اثر variable= است echo "(unset) variable = $variable" #$variable بدون مقدار است. if [ -z "$variable" ] # then echo "\$variable has zero length." fi exit 0
در اکثر مضمونها، یک متغیر تعریف نشده و متغیری که unset شده است، هم معنی هستند. اما، ساختار جایگزینی پارامتر ${parameter:-default} میتواند تفاوت میان این دو را تشخیص بدهد. |
فرمان export[4] متغیرها را برای تمام پردازشهای فرزند اسکریپتِ در حال اجرا یا پوسته قابلدسترس مینماید. یک مورد مهم کاربرد فرمان export، در فایلهای راهاندازی، برای مقداردهی و قابل دستیابی نمودن متغیرهای محیطی جهت پردازشهای بعدی کاربر است.
متاسفانه، روشی برای به عقب export کردن متغیرها به پردازش پدر وجود ندارد، export به پردازشی که اسکریپت را فراخوانی نموده یا پردازش پوسته میسر نیست. |
مثال 15-20. استفاده از export برای رد کردن یک متغیر به یک اسکریپت جاسازی شده awk
#!/bin/bash #بازهم یک نگارش دیگر از اسکریپت «جمعزننده ستون» (col-totaler.sh) #+ #این اسکریپت از محیط برای رد کردن یک متغیر اسکریپت به awk استفاده #+میکند و اسکریپت awk را در یک متغیر قرار میدهد. ARGS=2 E_WRONGARGS=85 if [ $# -ne "$ARGS" ] # then echo "Usage: `basename $0` filename column-number" exit $E_WRONGARGS fi filename=$1 column_number=$2 # export column_number #Export شماره ستون به محیط، بنابراین برای بازیابی در دسترس است. # awkscript='{ total += $ENVIRON["column_number"] } END { print total }' #بله، یک متغیر میتواند یک اسکریپت awk را دریافت کند. # #اکنون، اجرای اسکریپت awk awk "$awkscript" "$filename" #با تشکر از Stephane Chazelas exit 0
مقداردهی و export متغیرها در یک عمل امکانپذیر است، همچون در عبارت export var1=xxx. به هر حال، همانطور که Greg Keraunen توضیح میدهد، در برخی وضعیتها ممکن است این دارای اثری متفاوت با تنظیم یک متغیر و سپس صادر کردن(export) آن باشد.
bash$ export var=(a b); echo ${var[0]} (a b) bash$ var=(a b); export var; echo ${var[0]} a |
یک متغیر برای صادر شدن، ممکن است نیاز به تدبیر خاصی داشته باشد. مثال M-2 را ببینید. |
فرمانهای declare و typeset خصوصیات متغیرها را مشخص و-یا محدود میکنند.
همانند declare -r، یک متغیر را به صورت فقطخواندنی، در نتیجه، به عنوان یک ثابت تنظیم میکند. تلاش برای تغییر متغیر، همراه با یک پیغام خطا به شکست منجر میگردد. این مورد مشابهی برای توصیفکننده نوع const زبان C در پوسته است.
این ابزار قدرتمند، شناسههای فرمان داده شده به اسکریپت را تجزیه میکند. این مورد متشابه Bash با فرمان خارجی getopt و تابع کتابخانهای getopt آشنا برای برنامهنویسان C است. این ابزار، عبور دادن و الحاقِ گزینههای چندتایی [5] و شناسههای بهمپیوسته را برای یک اسکریپت مجاز میسازد (برای مثال scriptname -abc -e /usr/local).
ساختار getopts از دو متغیر ضمنی استفاده میکند. $OPTIND اشارهگر شناسه (OPTion INDex) است و $OPTARG شناسه (اختیاری) پیوست شده به یک گزینه (OPTion ARGument) است. یک کولن در انتهای نام گزینه در هنگام تعریف، آن گزینه را به عنوان گزینه دارای یک شناسهِ پیوست شده، مشخص میکند.
یک ساختار getopts معمولاً به صورت بستهبندی شده در یک حلقه while قرار میگیرد، که گزینهها و شناسهها را یکی یکی پردازش نموده سپس متغیر تلویحی $OPTIND را برای اشاره به مورد بعدی افزایش میدهد.
|
while getopts ":abcde:fg" Option # #a، b، c، d، e، f و g گزینههای (نشانگرهای) مورد انتظار هستند. #وجود :بعد از گزینه e نشان میدهد که دارای یک شناسهی همراه خواهد بود. do case $Option in a ) #انجام کاری با متغیر a. b ) #انجام کاری با متغیر b. ... e) #انجام کاری با متغیر e، و همچنین با $OPTARG که #شناسه عبور داده شده مرتبط با گزینه e است. ... g ) #انجام کاری با متغیر g. esac done shift $(($OPTIND - 1)) # #تمام اینها اصلاً به آن پیچیدگی که وانمود میشود نیست.
مثال 15-21. کاربرد getopts برای خواندن گزینهها-شناسههای داده شده به یک اسکریپت
#!/bin/bash #ex33.sh: به کارگیری getopts و OPTIND #اسکریپت ویرایش شده 10/09/03 به پیشنهاد Bill Gradwohl #در اینجا میبینیم که getopts چگونه شناسههای خط فرمان اسکریپت را پردازش میکند. # #فراخوانی اسکریپت را با موارد زیر امتحان کنید. # #(qOption میتواند رشتهای اختیاری باشد.) # # #+نتیجه غیر منتظره، r را به عنوان شناسه گزینه q به کار میگیرد # # # #(OPTIND در بیان اینکه یک گزینه از کجا آمده قابل اطمینان نیست.) #اگر یک گزینه انتظار یک شناسه ("flag:") داشته باشد، آنوقت آنچه #+ NO_ARGS=0 E_OPTERROR=85 if [ $# -eq "$NO_ARGS" ] # then echo "Usage: `basename $0` options (-mnopqrs)" exit $E_OPTERROR # # #توجه: خط تیره (-) لازم است. fi while getopts ":mnopq:rs" Option do case $Option in m ) echo "Scenario #1: option -m- [OPTIND=${OPTIND}]";; n | o ) echo "Scenario #2: option -$Option- [OPTIND=${OPTIND}]";; p ) echo "Scenario #3: option -p- [OPTIND=${OPTIND}]";; q ) echo "Scenario #4: option -q-\ with argument \"$OPTARG\" [OPTIND=${OPTIND}]";; #توجه کنید که گزینه q باید دارای یک شناسه مرتبط باشد، #+ r | s ) echo "Scenario #5: option -$Option-";; * ) echo "Unimplemented option chosen.";; # esac done shift $(($OPTIND - 1)) # #اکنون $1 به اولین مورد غیر گزینهای ارایه شده در خطفرمان در صورتیکه #+ exit $? #همچنان که Bill Gradwohl بیان میکند، «ساز و کار getopts به شخص اجازه #تعیین کردن scriptname -mnop -mnop را میدهد، اما برای تمیز دادن آنکه #+کدام از کجا آمده، روش قابل اطمینانی با کاربرد OPTIND وجود ندارد.» #
این فرمان، موقعی که از خط فرمان فراخوانی شده باشد، یک اسکریپت را اجرا میکند. داخل یک اسکریپت، یک source file-name فایل file-name را بارگذاری میکند. Source کردن یک فایل (dot-command) کد را به داخل اسکریپت وارد میکند، به اسکریپت پیوست میکند (مانند همان اثر رهنمود #include در یک برنامه C). پیامد کلی آن، همانند آن است که سطرهای کد «source شده» به طور فیزیکی در بدنه اسکریپت حضور داشته باشند. این فرمان در موقعیتهایی مفید است که چند اسکریپت از فایل دادهها یا تابع کتابخانهای مشترک استفاده میکنند.
مثال 15-22. «پیوست کردن» یک فایل داده
#!/bin/bash #توجه داشته باشید که این مثال باید با bash فراخوانی بشود، #+یعنی به شکل bash ex38.sh نه به صورت sh ex38.sh . data-file # #همان اثر source data-file، اما قابل حملتر. #فایل data-file باید در دایرکتوری کاری جاری موجود باشد، #+ # echo "variable1 (from data-file) = $variable1" echo "variable3 (from data-file) = $variable3" let "sum = $variable2 + $variable4" echo "Sum of variable2 + variable4 (from data-file) = $sum" echo "message1 (from data-file) is \"$message1\"" # echo "message2 (from data-file) is \"$message2\"" print_message This is the message-print function in the data-file. exit $?
فایل data-file برای مثال 15-22 فوق. باید در همان دایرکتوری حاضر باشد.
# # #با یک فرمان source یا . از یک اسکریپت پوسته فراخوانی میشود. # variable1=23 variable2=474 variable3=5 variable4=97 message1="Greetings from *** line $LINENO *** of the data file!" message2="Enough for now. Goodbye." print_message () { # if [ -z "$1" ] then return 1 # fi echo until [ -z "$1" ] do # echo -n "$1" # echo -n " " # shift # done echo return 0 }
اگر فایل منبع شده خودش یک اسکریپت قابل اجرا باشد، آنوقت اجرا خواهد گردید و بعد کنترل را به اسکریپتی که او را فراخونی نموده برگشت میدهد. یک اسکریپت قابل اجرای منبع شده ممکن است از یک return برای این منظور استفاده نماید.
شناسهها میتوانند (به طور اختیاری) به عنوان پارامترهای مکانی به فایل منبع شده عبور داده شوند.
source $filename $arg1 arg2
حتی برای اسکریپت امکانپذیر است که خودش را source کند، اگرچه به نظر نمیرسد که این کار هیچگونه مورد استفاده عملی داشته باشد.
مثال 15-23. یک اسکریپت (بیفایده) که خودش را منبع میکند
#!/bin/bash # #از جلد دوم "Stupid Script Tricks,". MAXPASSCNT=100 # echo -n "$pass_count " # #+چون $pass_count هنوز مقدار اولیه نگرفته است. let "pass_count += 1" #با فرض اینکه متغیر $pass_count بدون داشتن مقدار اولیه، میتواند در #+ #این در Bash و pdksh کار میکند، اما متکی به رفتار غیر قابل حمل #+ #بهتر است قبل از افزایش $pass_count مقدار اولیه 0 به آن تخصیص یابد. while [ "$pass_count" -le $MAXPASSCNT ] do . $0 # #./$0 (که بازگشت صحیح خواهد بود) در اینجا کار نمیکند. چرا؟ done # #+به طور موثر خودش را بسط میدهد، یعنی در هر دور از حلقه while #+با هر source در سطر 20 یک بخش از کد تولید میگردد # #البته، اسکریپت هر سطر دوباره منبع شده #! را به عنوان یک توضیح #+ echo exit 0 #پیامد کلی این اسکریپت شمارش از 1 تا 100 است. # # # #
به طور بدون قید و شرط اسکریپت را خاتمه میدهد. [6] فرمان exit به طور اختیاری میتواند یک شناسه صحیح دریافت کند، که به عنوان وضعیت خروج اسکریپت به پوسته برگشت داده میشود. پایان دادن حتی سادهترین اسکریپتها با یک exit 0 مشخص کننده یک اجرای موفق، تکنیک مناسبی است.
اگر اسکریپتی با یک exit فاقد یک شناسه خاتمه یابد، وضعیت خروج اسکریپت، وضعیت خروج آخرین فرمان اجرا شده در اسکریپت بدون به حساب آوردن exit است. این معادل یک exit $? است. |
یک فرمان exit همچنین میتواند برای خاتمه دادن به یک پوسته فرعی به کار برود. |
این builtin پوسته، پردازش جاری را با یک فرمان مشخص شده تعویض میکند. به طور عادی، موقعی که پوسته با یک فرمان مواجه میگردد، یک پردازش فرزند برای اجرای فرمان منشعب میکند. با استفاده از توکار exec پوسته انشعاب نمیزند، و فرمان exec شده، پوسته را تعویض میکند. بنابراین وقتی در اسکریپت استفاده شود، موقع خاتمه یافتن فرمان exec شده، یک خروج از اسکریپت را تحمیل میکند.[7]
#!/bin/bash exec echo "Exiting \"$0\" at line $LINENO." # #$LINENO یک متغیر داخلی Bash تنظیم شده به شماره سطری است که در آن قرار دارد. # # echo "This echo fails to echo." exit 99 # # #+را با یک echo $? کنترل کنید. مشاهده #خواهید نمود که مقدارش 99 نیست.
مثال 15-25. اسکریپتی که خودش را exec میکند
#!/bin/bash # #توجه: مجوزهای این اسکریپت را به 555 یا 755 تنظیم کنید، سپس #آن را با ./self-exec.sh یا sh ./self-exec.sh فراخوانی کنید. echo echo "This line appears ONCE in the script, yet it keeps echoing." echo "The PID of this instance of the script is still $$." # echo "==================== Hit Ctl-C to exit ====================" sleep 1 exec $0 # #+ echo "This line will never echo!" # exit 99 # #
یک exec همچنین برای تخصیص مجدد توصیفگرهایفایل به کار میرود. برای مثال، exec <zzz-file ورودی استاندارد را با فایل zzz-file تعویض میکند.
گزینه -exec برای فرمان find همان builtin پوسته exec نیست. |
این فرمان، تغییر وضعیت گزینههای پوسته را اجازه میدهد ( مثال 25-1 و مثال 25-2 را مشاهده نمایید). این فرمان اغلب در فایلهای راهاندازی Bash ظاهر میگردد، اما در اسکریپها نیز مورد استفاده دارد. به نگارش 2 یا جدیدتر Bash نیاز دارد.
shopt -s cdspell #غلط نوشتاری کوچک در نام دایرکتوری را برای cd مجاز میکند. #گزینه -s تنظیم میکند، گزینه -u غیر فعال میکند. cd /hpme #تایپ اشتباه /home pwd # #
قرار دادن یک فرمان caller در داخل یک تابع، اطلاعاتی در باره فراخواننده آن تابع به stdout بازتاب میدهد.
#!/bin/bash function1 () { #داخل تابع function1 () caller 0 # } function1 #سطر 9 اسکریپت # # #فراخوانی شده از بخش main اسکریپت #نام اسکریپت فراخواننده caller 0 #
یک فرمان caller همچنین میتواند اطلاعات فراخوانی کننده را از یک اسکریپت source شده در داخل یک اسکریپت دیگر برگشت بدهد. در مقایسه با تابع، این یک «فراخوانی زیر روال» است.
شما ممکن است در اشکالزدایی این فرمان را سودمند بیابید.
فرمانی که یک وضعیت خروج موفق (صفر) برگشت میدهد، اما کار دیگری انجام نمیدهد.
bash$ true bash$ echo $? 0
# while true #مستعاری برای ":" do operation-1 operation-2 ... operation-n # done
فرمانی که یک وضعیت خروج ناموفق برگشت میدهد، اما هیچ کار دیگری انجام نمیدهد.
bash$ false bash$ echo $? 1
#آزمایش فرمان false if false then echo "false evaluates \"true\"" else echo "false evaluates \"false\"" fi # #ایجاد حلقه while false (حلقه تهی) while false do # operation-1 operation-2 ... operation-n # done
مشابه فرمان خارجی which، فرمان type [cmd] شناسهاش «cmd» را تعیین هویت میکند. برخلاف which، فرمان type در Bash یک builtin است. گزینه مفید -a با type کلمهکلیدیها و builtinها را شناسایی کرده، و فرمانهای سیستم با همان نامها را نیز مکانیابی مینماید.
bash$ type '[' [ is a shell builtin bash$ type -a '[' [ is a shell builtin [ is /usr/bin/[ bash$ type type type is a shell builtin
فرمان type برای بررسی وجود یک فرمان معین میتواند مفید باشد.
نام مسیر فرمانهای مشخص شده را ذخیره میکند -- در جدول hash پوسته[8] -- به طوریکه پوسته یا اسکریپت در فراخوانیهای بعدی آن فرمانها نیازی به جستجوی $PATH ندارد. موقعی که hash بدون شناسه فراخوانی میشود، فقط فرمانهایی را که hash شدهاند لیست میکند. گزینه -r جدول hash را از نو تنظیم میکند.
bind یک builtin است که عمل تخصیص یافته به کلیدها در readline [9] را نمایش میدهد یا ویرایش میکند.
خلاصهی کوتاهی از نحوه کاربرد یک builtin پوسته را ارایه میکند. این همتای whatis است، اما برای builtinها. نمایش اطلاعات help در انتشار نگارش 4 پوسته Bash یک بهروزرسانی بسیار ضروری را فراهم نمود.
bash$ help exit exit: exit [n] Exit the shell with a status of N. If N is omitted, the exit status is that of the last command executed.
[1] | به طوری که Nathan Coulter توضیح میدهد، «در حالیکه منشعب کردن یک پردازش یک عمل کم هزینه است، اجرای یک برنامه جدید در پردازش فرزند به تازگی منشعب شده بالاسری بیشتری اضافه میکند.» |
[2] | یک استثنا برای این مورد، فرمان time است که در مستندات رسمی Bash به عنوان یک کلیدواژه («کلمه رزرو شده») لیست گردیده است. |
[3] | توجه نمایید که let نمیتواند برای تنظیم متغیرهای رشتهای به کار برود. |
[4] | Export(صادر) کردن اطلاعات، معتبر ساختن آن در مضمون همگانیتر است. همچنین محدوده را مشاهده کنید. |
[5] | یک گزینه شناسهای است که به عنوان یک نشانگر، راهگزینی روشن و خاموش کردن رفتارهای اسکریپت عمل میکند. شناسه مرتبط شده با یک گزینه بخصوص رفتاری را که گزینه (نشانگر) روشن یا خاموش میکند، بیان مینماید. |
[6] | از نظر تکنیکی، یک exit فقط پردازشی (یا پوستهای) را که در آن در حال اجرا هست ،نه پردازش پدر را، خاتمه میدهد. |
[7] | مگر اینکه exec برای دوباره تخصیص دادن توصیفگرهای فایل به کار برود. |
[8] |
Hashing یک روش ایجاد کلیدهای مراجعه به دادههای ذخیره شده در یک جدول است. برای ایجاد کلیدها خود اقلام دادهها، با استفاده از تعدادی الگوریتم (روش، یا دستورالعمل) ساده ریاضی «درهم آمیخته» میشوند. یک مزیت hashing سرعت آن است. یک کمبودش آن است که تصادمها -- در جایی که یک کلید واحد به بیش از یک قلم داده ترسیم میگردد -- امکانپذیر هستند. برای نمونههای hash کردن مثال A-20 و مثال A-21 را ببینید. |
[9] | کتابخانه readline چیزی است که Bash در یک پوسته محاورهای برای خواندن ورودی به کار میبرد. |
#!/bin/bash
while true
do
read -sn1 a
test "$a" == `echo -en "\e"` || continue
read -sn1 a
(test "$a" == "[" || continue) || (test "$a" == "O" || continue)
read -sn1 a
case "$a" in
A) echo "up";;
B) echo "down";;
C) echo "right";;
D) echo "left";;
6) echo "pgDn";;
5) echo "pgUp";;
3) echo "delete";;
2) echo "insert";;
H|1) echo "home";; #
(برگشت)