انواع متغیر خاص

فصل 4. معرفی متغیرها و پارامترها

‎4.4‎- انواع متغیر خاص

متغیرهای محلی

متغیرهای قابل مشاهده فقط در داخل قطعه کد یا تابع (همچنین متغیرهای محلی در توابع را ببینید)

متغیرهای محیطی

متغیرهایی که بر رفتار پوسته و رابط کاربر اثر می‌گذارند


در یک مفهوم کلی‌تر، هر پردازش دارای یک «محیط» است، یعنی یک گروه از متغیرها که پردازش می‌تواند به آنها رجوع کند. از این جهت، پوسته نیز مانند هر پردازش دیگری رفتار می‌نماید.

هر نوبت که یک پوسته شروع می‌شود، متغیرهای پوسته‌ای تولید می‌کند که مطابق متغیرهای محیط خودش می‌باشد. به روزرسانی یا افزودن متغیرهای محیطی جدید باعث می‌شود پوسته محیطش را به روزرسانی کند، و تمام پردازشهای فرزند پوسته (فرمانهایی که اجرا می‌کند) این محیط را به ارث ببرند.


Caution

فضای اختصاص‌یافته به محیط محدود است. ایجاد متغیرهای محیطی بسیار زیاد یا یک متغیری که فضای مفرطی مصرف می‌کند، ممکن است باعث مشکلاتی گردد.

bash$ eval "`seq 10000 | sed -e 's/.*/export var&=ZZZZZZZZZZZZZZ/'`"

bash$ du
bash: /usr/bin/du: Argument list too long

یادداشت: این خطا از کرنل نگارش ‎2.6.23 برطرف گردیده است‎.

(تشکر از Stéphane Chazelas برای شفاف‌سازی و ارائه مثال فوق.)


اگر یک اسکریپت متغیرهای محیطی تنظیم کند، لازم است آن متغیرها «صادر» بشوند یعنی، به محیط داخلی اسکریپت گزارش بشوند. این کار، وظیفه فرمان export است.

یک اسکریپت فقط می‌تواند متغیرها را به پردازش‌های فرزند export نماید، یعنی تنها به فرمانها یا پردازشهایی که آن اسکریپت بخصوص آنها را آغاز کرده است. یک اسکریپتِ فراخوانی شده از خط فرمان نمی‌تواند متغیرها را به عقب، به خط فرمان صادر نماید. پردازشهای فرزند نمی‌توانند متغیرها را به پردازشهای والدی که آنها را تولید مثل کرده‌اند صادر کنند.

تعریف: یک پردازش فرزند، پردازش فرعی راه‌اندازی شده توسط پردازش دیگر، یعنی پدرش است.


پارامترهای مکانی

شناسه‌های عبور داده شده از خط فرمان به اسکریپت [1]: ‎$0‎‏، ‎$1‎‏، ‎$2‎‏، ‎$3‎ ‏‏. . .

‎$0‎ نام خود اسکریپت است، ‎$1‎ اولین شناسه است، ‎$2‎ دومین، ‎$3‎ سومین، و به همین ترتیب. [2] بعد از ‎$9‎، شناسه‌ها باید در ابروها محصور بشوند، برای مثال، ‎${10}‎‏، ‎${11}‎‏، ‎${12}‎.

متغیرهای خاص ‎$*‎ و ‎$@‎ تمامِ پارامترهای مکانی را مشخص می‌کنند.

مثال ‎4-5‎. پارامترهای مکانی

#!/bin/bash

#
#

MINPARAMS=10

echo

echo "The name of this script is \"$0\"."
#               
echo "The name of this script is \"`basename $0`\"."
#

echo

if [ -n "$1" ]              #         
then
 echo "Parameter #1 is $1"  #
fi 

if [ -n "$2" ]
then
 echo "Parameter #2 is $2"
fi 

if [ -n "$3" ]
then
 echo "Parameter #3 is $3"
fi 

# ...


if [ -n "${10}" ]  #
then
 echo "Parameter #10 is ${10}"
fi 

echo "-----------------------------------"
echo "All the command-line parameters are: "$*""

if [ $# -lt "$MINPARAMS" ]
then
  echo
  echo "This script needs at least $MINPARAMS command-line arguments!"
fi  

echo

exit 0

نشانه‌گذاری Bracket (ابرو) برای پارامترهای مکانی، به روش نسبتاً ساده‌ای برای ارجاع به آخرین شناسه‌ای که در خط فرمان به اسکریپت عبور داده شده، منجر می‌گردد. این کار به ارجاع غیر مستقیم نیز نیاز دارد.

args=$#           #
lastarg=${!args}
#


#
#
#

برخی اسکریپت‌ها بسته به نامی که با آن فراخوانی می‌گردند، می‌توانندعملیات متفاوتی انجام بدهند. برای انجام این کار، لازم است اسکریپت پارامتر ‎$0‎، یعنی نامی را که بواسطه آن فراخوانی شده است، بررسی کند. [3] همچنین باید پیوندهای نمادین برای تمام نام‌های پیشنهادی اسکریپت وجود داشته باشد. مثال ‎16-2‎.

Tip

اگر اسکریپتی یک پارامتر خط فرمان انتظار داشته باشد اما بدون یک پارامتر فراخوانی گردد، این کار ممکن است موجب یک تخصیص متغیر تهی، یا به طور کلی یک نتیجه نامطلوب بشود. یک راه پیشگیری از آن، درج کردن یک کاراکتر اضافی در هر دو طرف جمله تخصیص به کار رفته برای پارامتر مکانی مورد نظر است.


variable1_=$1_  #
#           ‎

critical_argument01=$variable1_

#                             
variable1=${variable1_/_/}
#
#

# 
#+ 
if [ -z $1 ]
then
  exit $E_MISSING_POS_PARAM
fi


#
#+
#              
#
#                  

---

مثال ‎4-6‎. wh، مراجعه whois به نام قلمرو

#!/bin/bash
#

#
#

#

#          
#
#
#

E_NOARGS=75


if [ -z "$1" ]
then
  echo "Usage: `basename $0` [domain-name]"
  exit $E_NOARGS
fi

#  
case `basename $0` in    #
    "wh"       ) whois $1@whois.tucows.com;;
    "wh-ripe"  ) whois $1@whois.ripe.net;;
    "wh-apnic" ) whois $1@whois.apnic.net;;
    "wh-cw"    ) whois $1@whois.cw.net;;
    *          ) echo "Usage: `basename $0` [domain-name]";;
esac 

exit $?

---

فرمان shiftدر حقیقت پارامترهای مکانی را در اثر انتقال آنها یک پارامتر به چپ، دوباره اختصاص می‌دهد.

‎$1‎ ‎<--- $2‎‏، ‎$2 <--- $3‎‏، ‎$3 <--- $4‎‏، وغیره.

پارامتر ‎$1‎ قدیمی ناپدید می‌گردد، اما ‎$0‎ (نام اسکریپت) تغییر نمی‌کند. اگر شما تعداد پارامترهای مکانی بسیاری برای یک اسکریپت به کار ببرید، فرمان shift به شما اجازه می‌دهد به پارامترهای از ‎10‎ به بعد دسترسی داشته باشید، اگرچه نشانه‌گذاری ‎{bracket}‎ نیز این کار را میسر می‌سازد.

مثال ‎4-7‎. کاربرد shift

#!/bin/bash
# 

#
#+
#

until [ -z "$1" ]  #
do
  echo -n "$1 "
  shift
done

echo               #

#
echo "$2"
#

#
#+
#

exit

#
#+

فرمان shift می‌تواند یک پارامتر عددی تعیین کننده تعداد جابجایی را بپذیرد.

#!/bin/bash
#

shift 3    #
#
#

echo "$1"

exit 0

#


$ sh shift-past.sh 1 2 3 4 5
4

#
#+
#+
#+
#
#
      until [ -z "$1" ]
      do
         echo -n "$1 "
         shift 20    #
      done           #+
#
#
#
#


فرمان shift با پارامترهای عبور داده شده به یک تابع نیز به سبک مشابهی کار می‌کند. مثال ‎36-18‎ را ببینید.

یادداشت‌ها

[1]

توجه نمایید که تابع‌ها نیز پارامترهای مکانی می‌گیرند.

[2]

پردازش فراخواننده اسکریپت پارامتر ‎$0‎ را تنظیم می‌کند. مطابق قرارداد، این پارامتر نام اسکریپت است. manpage (صفحه مستندات) برای execv را ببینید.

با وجود این از خط فرمان، ‎$0‎ نام پوسته است.

bash$ echo $0
bash

tcsh% echo $0
tcsh

[3]

اگر اسکریپت منبع شده یا لینک شده باشد، آنوقت این مورد عمل نخواهد کرد. مطمئن‌تر است که ‎$BASH_Source‎ بررسی گردد.