Builtinها: | متغیرهای مؤثر بر رفتار اسکریپتهای bash |
$BASH | مسیر فایل باینری خود Bash bash$ echo $BASH /bin/bash |
$BASH_ENV | یک متغیر محیطی که به یک فایل راهانداز Bash اشاره میکند تا هنگامی که یک اسکریپت احضار میگردد، خوانده شود |
$BASH_SUBSHELL | متغیری که نشاندهنده رتبه پوسته فرعی است. این یک افزایش جدید به Bash نگارش 3 است. برای نحوه کاربرد آن مثال 21-1 را ببینید. |
$BASHPID | شماره شناسایی پردازش نمونه Bash جاری. این با متغیر $$ یکسان نیست، اما بیشتر اوقات همان نتیجه را ارایه میکند.
bash4$ echo $$ 11015 bash4$ echo $BASHPID 11015 bash4$ ps ax | grep bash4 11015 pts/2 R 0:00 bash4 #!/bin/bash4 echo "\$\$ outside of subshell = $$" # echo "\$BASH_SUBSHELL outside of subshell = $BASH_SUBSHELL" # echo "\$BASHPID outside of subshell = $BASHPID" # echo ( echo "\$\$ inside of subshell = $$" # echo "\$BASH_SUBSHELL inside of subshell = $BASH_SUBSHELL" # |
$BASH_VERSINFO | یک آرایه ۶ عضوی شامل اطلاعاتی در باره نگارش Bash نصب شده است. این مورد مشابه $BASH_VERSION پایین، اما یک مقداری مفصلتر است.
# for n in 0 1 2 3 4 5 do echo "BASH_VERSINFO[$n] = ${BASH_VERSINFO[$n]}" done # # # # # # # |
$BASH_VERSION | نگارش Bash نصب شده روی سیستم
bash$ echo $BASH_VERSION 3.2.25(1)-release tcsh% echo $BASH_VERSION BASH_VERSION: Undefined variable. کنترل $BASH_VERSION شیوه مناسبی برای تعیین آن است که کدام پوسته در حال اجرا است. $SHELL لزوماً پاسخ صحیح نخواهد داد. |
$CDPATH | یک لیست معتبر جستجوی مسیرها برای فرمان cd است که اقلام آن با کاراکتر کولن از هم جدا میشوند، مشابه نقش متغیر $PATH برای فایلهای اجرایی. متغیر $CDPATH میتواند در فایل محلی ~/.bashrc تنظیم بشود. bash$ cd bash-doc bash: cd: bash-doc: No such file or directory |
$DIRSTACK | کمیت فوقانی در پشته دایرکتوری [1] (تاثیر پذیرنده از pushd و popd) این متغیر داخلی با فرمان dirs رابطه دارد، اگرچه dirs تمام محتویات پشته دایرکتوری را نمایش میدهد. |
$EDITOR | ویرایشگر قراردادی فراخوانی شونده توسط یک اسکریپت، به طور معمول vi یا emacs. |
$EUID | شماره ID کاربر «مؤثر» شماره شناسایی هر آنکه هویت کاربر جاری را به خود گرفته است، شاید بوسیله su. $EUID لزوماً همانند $UID نیست. |
$FUNCNAME | نام تابع جاری xyz23 () { echo "$FUNCNAME now executing." # } xyz23 echo "FUNCNAME = $FUNCNAME" # # همچنین مثال A-50 را ببینید. |
$GLOBIGNORE | لیستی از الگوهای نام فایل که باید از مطابقت آنها در globbing صرفنظر بشود. |
$GROUPS | گروههایی که کاربر جاری متعلق به آنها است این یک لیست (آرایه) از شمارههای شناسایی گروههای کاربر جاری، همانطور که در فایل /etc/passwd و /etc/group ثبت گردیده است. root# echo $GROUPS 0 root# echo ${GROUPS[1]} 1 root# echo ${GROUPS[5]} 6 |
$HOME | دایرکتوری خانه کاربر، معمولاً /home/username (مثال 10-7 را ببینید) |
$HOSTNAME | فرمان hostname موقع بالا آمدن سیستم، نام میزبان سیستم را در یک اسکریپت init تعیین میکند. اگرچه، در Bash تابع gethostname() متغیر داخلی $HOSTNAME را تنظیم میکند. همچنین مثال 10-7 را ببینید. |
$HOSTTYPE | نوع میزبان همانند $MACHTYPE، سختافزار سیستم را تعیین میکند. bash$ echo $HOSTTYPE i686 |
$IFS | جداکننده فیلد داخلی این متغیر تعیین میکند که Bash در زمان تفسیر رشتههای کاراکتری چگونه فیلدها، یا حدود کلمات را تشخیص میدهد. $IFS به طور پیشفرض فضای سفید (فاصله، tab، و سطر جدید) قرار داده میشود، اما میتواند تغییر یابد، برای مثال، به منظور تجزیه یک فایل دادهای که در آن کاراکتر کاما جداکننده باشد. توجه نمایید که $* اولین کاراکتر نگهداری شده در $IFS را استفاده میکند. مثال 5-1 را ببینید. bash$ echo "$IFS" # bash$ echo "$IFS" | cat -vte ^I$ $ # # bash$ bash -c 'set w x y z; IFS=":-;"; echo "$*"' w:x:y:z # #+ تنظیم $IFS برای زدودن فضای سفید از نام مسیرها. IFS="$(printf '\n\t')" # $IFS همانطور که با سایر کاراکترها رفتار میکند با فضای سفید عمل نمیکند. مثال 9-1. $IFS و فضای سفید #!/bin/bash # var1="a+b+c" var2="d-e-f" var3="g,h,i" IFS=+ # echo $var1 # echo $var2 # echo $var3 # echo IFS="-" # # echo $var1 # echo $var2 # echo $var3 # echo IFS="," # # echo $var1 # echo $var2 # echo $var3 # echo IFS=" " # # echo $var1 # echo $var2 # echo $var3 # # ===================================================== # # # #+ output_args_one_per_line() { for arg do echo "[$arg]" done # } echo; echo "IFS=\" \"" echo "-------" IFS=" " var=" a b c " # output_args_one_per_line $var # # # # echo; echo "IFS=:" echo "-----" IFS=: var=":a::b:c:::" # # #+ output_args_one_per_line $var # # # # # # # # # echo exit (تشکر بسیار از Stéphane Chazelas برای شفافسازی و مثالهای بالا.) همچنین مثال 16-41، مثال 11-8، و مثال 19-14 را برای موارد آموزنده استفاده از $IFS ببینید. |
$IGNOREEOF | چشمپوشی از EOF: پوسته قبل از قطع اتصال از این تعداد انتهای فایل (control-D) چشمپوشی خواهد نمود. |
$LC_COLLATE | بیشتر اوقات در فایلهای .bashrc یا /etc/profile تنظیم میشود، این متغیر ترتیب مطابقت در بسط نامفایل و انطباق الگو را کنترل میکند. اگر به طور نادرست به کار برود، LC_COLLATE میتواند باعث ننایج غیر منتظره در جانشینی نامفایل بشود. Bash از نگارش 2.05 دیگر در جانشینی نامفایل میان حروف کوچک و حروف بزرگ کاراکترهای دامنه داخل براکتها تمایز قایل نمیگردد. برای مثال، ls [A-M]* با هر دو نام File1.txt و file1.txt منطبق خواهد شد. برای برگشت به رفتار مرسومِ انطباق براکتها، LC_COLLATE را به وسیله یک export LC_COLLATE=C در فایل /etc/profile و/یا ~/.bashrc به C تنظیم کنید. |
$LC_CTYPE | این متغیر داخلی تفسیر کاراکتر در globbing و انطباق الگو را کنترل میکند. |
$LINENO | این متغیر محتوی شماره سطری از اسکریپت پوسته است که این متغیر در آن سطر ظاهر میگردد. فقط داخل اسکریپتی که در آن ظاهر میشود اهمیت دارد، و به ویژه برای مقاصد اشکالزدایی سودمند است.
# last_cmd_arg=$_ # echo "At line number $LINENO, variable \"v1\" = $v1" echo "Last command argument processed = $last_cmd_arg" # |
$MACHTYPE | نوع ماشین سختافزار سیستم را تعیین میکند. bash$ echo $MACHTYPE i686 |
$OLDPWD | دایرکتوری کاری سابق («نشان دایرکتوری کاری سابق»، دایرکتوری قبلی که شما در آن بودهاید). |
$OSTYPE | نوع سیستمعامل bash$ echo $OSTYPE linux |
$PATH | مسیر فایلهای اجرایی، به طور معمول /usr/bin/، /usr/X11R6/bin/، /usr/local/bin، و غیره. وقتی فرمانی داده میشود، پوسته به طور خودکار در دایرکتوریهای فهرست شده در path، یک جستجوی سریع برای یافتن فایل قابل اجرا انجام میدهد. path یعنی لیستی از دایرکتوریها که با کاراکتر کولن تفکیک گردیدهاند، در متغیر محیطی $PATH ذخیره شده است. به طور عادی، سیستم تعریف $PATH را در /etc/profile و/یا ~/.bashrc ذخیره میکند( پیوست H را ببینید).
bash$ echo $PATH /bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin:/sbin:/usr/sbin عبارت PATH=${PATH}:/opt/bin دایرکتوری /opt/bin را در path فعلی درج میکند. ممکن است در یک اسکریپت، افزودن موقتی یک دایرکتوری از این طریق به path، سودمند باشد. موقعی که اسکریپت خارج گردد، $PATH اصلی بازیابی میشود( یک پردازش فرزند، از قبیل یک اسکریپت، نمیتواند محیط پردازش پدر، یعنی پوسته را تغییر بدهد). به عنوان یک اقدام پیشگیرانه امنیتی، «دایرکتوری کاری» جاری، ./، معمولاً در $PATH ذکر نمیگردد. |
$PIPESTATUS | متغیر آرایه نگهدارنده وضعیت خروج(های) آخرین لوله اجرا شده در پیشزمینه. bash$ echo $PIPESTATUS 0 bash$ ls -al | bogus_command bash: bogus_command: command not found bash$ echo ${PIPESTATUS[1]} 127 bash$ ls -al | bogus_command bash: bogus_command: command not found bash$ echo $? 127 عناصر آرایه متغیر $PIPESTATUS ممکن است در یک پوسته لاگین شامل یک کمیت 0 نادرست باشد(در نگارشهای قبل از Bash 3.0). tcsh% bash bash$ who | grep nobody | sort bash$ echo ${PIPESTATUS[*]} 0 1 0 سطرهای فوق در یک اسکریپت خروجی مورد انتظار 0 1 0 را تولید خواهد نمود. با تشکر از Wayne Pollock برای اشاره به این مطلب و ارسال مثال فوق.
متغیر $PIPESTATUS در برخی مضمونها نتایج غیرقابل انتظاری میدهد.
bash$ echo $BASH_VERSION 3.00.14(1)-release bash$ ls | bogus_command | wc bash: bogus_command: command not found 0 0 0 bash$ echo ${PIPESTATUS[@]} 141 127 0 Chet Ramey خروجی فوق را وابسته به رفتار ls میداند. اگر ls در یک pipe بنویسد که خروجیاش خوانده نشود، آنوقت SIGPIPE آن را kill میکند، و وضعیت خروج آن 141 است. وگرنه، همانطور که انتظار میرود وضعیت خروج آن 0 است. این مورد برای tr نیز صادق است. $PIPESTATUS یک متغیر «بیثبات» است. لازم است بلافاصله پس از لوله مورد بحث، قبل از آنکه هر فرمان دیگری مداخله کند، ضبط بشود.
bash$ ls | bogus_command | wc bash: bogus_command: command not found 0 0 0 bash$ echo ${PIPESTATUS[@]} 0 127 0 bash$ echo ${PIPESTATUS[@]} 0 در مواردی که $PIPESTATUS اطلاعات مطلوب را بیان نمیکند، ممکن است گزینه pipefail مفید باشد. |
$PPID | $PPID یک پردازش، ID پردازش (pid) فرایند والد آن است. [2] این متغیر را با فرمان pidof مطابقت بدهید. |
$PROMPT_COMMAND | متغیر نگهداری کننده فرمانی است که درست قبل از اینکه اعلان فرمان اصلی $PS1 نمایش داده شود، اجرا میگردد. |
$PS1 | این متغیر محتوی اعلان فرمان اصلی است که در خط فرمان دیده میشود. |
$PS2 | اعلان ثانوی، مشاهده شده در موقعی که ورودی اضافی مورد انتظار است. به صورت «>» ظاهر میشود. |
$PS3 | سومین اعلان، نمایش یافته در یک حلقه select ( مثال 11-30 را ببینید). |
$PS4 | چهارمین اعلان، نمایش یافته در ابتدای هر سطرِ خروجی در زمانیکه یک اسکریپت با گزینه -x [پیگردی تفصیلی] فراخوانی شده باشد. به صورت «+» نمایش داده میشود. به عنوان مساعدت در اشکالیابی، ممکن است جاسازی نمودن اطلاعات تشخیصی در متغیر $PS4 مفید باشد. P4='$(read time junk < /proc/$$/schedstat; echo "@@@ $time @@@ " )' # set -x # |
$PWD | دایرکتوری کاری (دایرکتوری که در حال حاضر در آن هستید) قابل قیاس با فرمان داخلی pwd است. #!/bin/bash E_WRONG_DIRECTORY=85 clear # TargetDirectory=/home/bozo/projects/GreatAmericanNovel cd $TargetDirectory echo "Deleting stale files in $TargetDirectory." if [ "$PWD" != "$TargetDirectory" ] then # echo "Wrong directory!" echo "In $PWD, rather than $TargetDirectory!" echo "Bailing out!" exit $E_WRONG_DIRECTORY fi rm -rf * rm .[A-Za-z0-9]* # # |
$REPLY | در صورتیکه برای فرمان read متغیری فراهم نشده باشد، متغیر پیشفرض است. همچنین قابل کاربرد در منوهای select، اما فقط شماره ردیف متغیر انتخاب شده را تامین میکند، نه کمیت خود متغیر. #!/bin/bash # |
$SECONDS | تعداد ثانیههایی که اسکریپت در حال اجرا بوده است. #!/bin/bash TIME_LIMIT=10 INTERVAL=1 echo echo "Hit Control-C to exit before $TIME_LIMIT seconds." echo while [ "$SECONDS" -le "$TIME_LIMIT" ] do # |
$SHELLOPTS | فهرست گزینههای فعال شده پوسته، یک متغیر فقط خواندنی. bash$ echo $SHELLOPTS braceexpand:hashall:histexpand:monitor:history:interactive -comments:emacs |
$SHLVL | مرحله پوسته، تعداد دفعاتی که Bash به طور عمقی تو در تو شده است. [3] اگر در خط فرمان $SHLVL برابر 1باشد، آنوقت در یک اسکریپت به 2 افزایش خواهد یافت. این متغیر تحت تاثیر پوستههای فرعی قرار نمیگیرد. موقعی که به میزان تو در تویی پوستههای فرعی نیاز دارید از $BASH_SUBSHELL استفاده کنید. |
$TMOUT | اگر متغیر محیطی $TMOUT به یک مقدار زمان غیر صفر تنظیم گردد، آنوقت اعلان پوسته بعد از $time ثانیه توقف خواهد نمود. این سبب یک قطع ارتباط(logout) خواهد شد. از نگارش 2.05b در Bash، در یک اسکریپت استفاده از $TMOUT در ترکیب با فرمان read امکانپذیر است. # روشهای پیچیدهتر دیگری برای پیادهسازی زمانبندی ورودی در یک اسکریپت وجود دارد. یک پیشنهاد، تنظیم یک حلقه زمانسنج برای ارسال سیگنال به اسکریپت پس از انقضای مهلت است. این کار همچنین به یک روال مدیریت سیگنال برای trap ( مثال 32-5 را ببینید) وقفه تولید شده توسط حلقهِ تنظیم زمان احتیاج دارد(واه!). #!/bin/bash # # یک پیشنهاد، استفاده از stty است. مثال 9-3. بار دیگر، ورودی زماندار #!/bin/bash # # گویا سادهترین روش کاربرد گزینه -t با فرمان read است. #!/bin/bash # # |
$UID | شماره ID کاربر شماره شناسایی کاربر جاری، همچنانکه در /etc/passwd ثبت گردیده است. این شماره id واقعی کاربر جاری است، حتی اگر او به طور موقت از طریق su یک هویت دیگری به خود گرفته باشد. $UID یک متغیر فقط خواندنی است، در معرض تغییر یافتن از خط فرمان یا داخل یک اسکریپت نیست، و همتای فرمان داخلی id است. #!/bin/bash # ROOT_UID=0 # همچنین مثال 2-3 را ببینید. متغیرهای $ENV، $LOGNAME، $MAIL، $TERM، $USER، و $USERNAME فرمانهای داخلی Bash نیستند. اگرچه بیشتر اوقات اینها به عنوان متغیرهای محیطی در یکی از فایلهای راهاندازی Bash تنظیم میشوند. $SHELL، نام پوسته لاگین کاربر، ممکن است از /etc/passwd یا در یک اسکریپت «init» تنظیم شده باشد، و علاوه براین، داخلی Bash هم نیست.
tcsh% echo $LOGNAME bozo tcsh% echo $SHELL /bin/tcsh tcsh% echo $TERM rxvt bash$ echo $LOGNAME bozo bash$ echo $SHELL /bin/tcsh bash$ echo $TERM rxvt |
پارامترهای مکانی
$0, $1, $2, etc. | پارامترهای مکانی، از سطرفرمان به اسکریپت عبور داده میشوند، به یک تابع تحویل میشوند، یا با یک متغیر set میشوند ( مثال 4-5 و مثال 15-16 را ببینید) |
$# | تعداد شناسههای سطرفرمان [4] یا پارامترهای مکانی (مثال 36-2 را ببینید) |
$* | تمام پارامترهای مکانی، به صورت یک کلمه واحد «$*» باید نقلقولی شده باشد |
$@ | همچون $*، اما هر پارامتر یک رشته نقلقول شده است، یعنی پارامترها دست نخورده و سالم، بدون تفسیر یا بسط، تحویل میشوند. این به معنای آن است که هر پارامتر از لیست شناسهها به صورت یک کلمه جداگانه دیده میشود. البته، «$@» باید نقلقولی شده باشد.
مثال 9-6. arglist: لیست کردن شناسهها با $* و $@ #!/bin/bash # # با یک shift در ادامه، $@ بقیه پارامترهای سطر فرمان را، بدون $1 قبلی که از دست رفته است، نگهداری میکند. #!/bin/bash # پارامتر ویژه $@ به عنوان ابزاری برای فیلتر کردن ورودی به داخل اسکریپتها مورد استفاده مییابد. ساختار cat "$@" ورودی برای یک اسکریپت را از stdin یا فایلهای ارایه شده به عنوان شناسه های اسکریپت، میپذیرد. مثال 16-24 و مثال 16-25 را ببینید. گاهی اوقات پارامترهای $* و $@ برحسب تنظیم متغیر $IFS رفتار متناقض و متحیر کنندهای نمایش میدهند. مثال 9-7. رفتار متناقض $* و $@ #!/bin/bash # پارامترهای $@ و $* فقط وقتی در میان نقلقولهای دوگانه باشند، تفاوت دارند.
مثال 9-8. پارامترهای $* و $@ هنگامی که $IFS تهی باشد #!/bin/bash # |
سایر پارامترهای ویژه
$- | نشانگرهای صادر شده به اسکریپت (با استفاده از set). مثال 15-16 را ببینید. این پارامتر ویژه، در ابتدا یک ابداع ksh بود که داخل Bash پذبرفته شد، و متاسفانه به نظر نمیرسد در اسکریپتهای Bash به طور قابل اعتمادی کار کند. یک مورد استفاده احتمالی آن، داشتن یک اسکریپت خود کنترلی برای محاورهای بودن است. |
$! | PID (ID پردازش) آخرین job در حال اجرای پسزمینه LOG=$0.log COMMAND1="sleep 100" echo "Logging PIDs background commands for script: $0" >> "$LOG" # به کار بردن $! جهت کنترل job: possibly_hanging_job & { sleep ${TIMEOUT}; eval 'kill -9 $!' &> /dev/null; } # # یا به طور جایگزین: # # TIMEOUT=30 # count=0 possibly_hanging_job & { while ((count < TIMEOUT )) do eval '[ ! -d "/proc/$!" ] && ((count = TIMEOUT))' # |
$_ | متغیر خاص تنظیم شده به شناسه پایانی فرمان اجرا شده قبلی است. مثال 9-9. متغیر Underscore (خط زیر) #!/bin/bash echo $_ # # |
$? | وضعیت خروج یک فرمان، تابع، یا خود اسکریپت ( مثال 24-7 را ببینید) |
$$ | ID پردازش (PID) خود اسکریپت. [5] متغیر $$ بیشتر اوقات برای ساختن نام فایلهای موقتی «منحصر به فرد» مورد استفاده پیدا میکند ( مثال 32-6، مثال 16-31، و مثال 15-27 را ببینید). این کار معمولاً سادهتر از فراخوانی mktemp است. |
[1] | ثبات آدرس پشته، یک مجموعه محلهای حافظه پیاپی است، به نوعی که مقادیر ذخیره شده (pushed) به یک ترتیب وارونه بازیابی (popped) میشوند. آخرین مقدار ذخیره شده اولین مورد بازیابی است. این مطلب گاهی اوقات LIFO (last-in-first-out) یا pushdown پشته نامیده میشود. |
[2] | البته PID اسکریپت جاری در حال اجرا $$ است. |
[3] | تا اندازهای قابل مقایسه با recursion، در این مضمون تو در تویی به یک الگوی جاسازی شده داخل الگوی بزرگتر اشاره دارد. یکی از تعاریف nest مطابق ویرایش 1913 فرهنگ لغات Webster، به خوبی این را تشریح میکند: "مجموعهای از جعبهها، صندوقها، یا نوع مشابه با اندازه درجهبندی شده، که هر کدام داخل یکی بزرگتر قرار گرفته." |
[4] | کلمات «شناسه» و «پارامتر» بیشتر اوقات به طور قابل معاوضه به کار میروند. در مضمون این سند، آنها دارای معنی دقیق یکسان هستند: یک متغیر عبور داده شده به یک اسکریپت یا تابع. |
[5] | داخل یک اسکریپت، درون یک پوسته فرعی، $$ شماره PID اسکریپت را برگشت میدهد، نه PID پوسته فرعی را. |