حلقه‌ها

فصل ‎11‎- حلقه‌ها و انشعاب‌ها

‎11.1‎- حلقه‌ها

یک حلقه، قطعه کدی است که مشروط به صحیح بودن شرط کنترل حلقه، لیستی از فرمانها را تکرار می‌کند. ‎[1]‎

حلقه‌های for

‎for arg in [list]

این ساختار اصلی ایجاد حلقه است. به طور قابل توجهی با شکل همتایش در C تفاوت دارد.

‎for arg in [list]‎
do
 command(s)...
done

در هر نوبت عبور از میان حلقه، arg مقدار یکی از متغیرهای متوالی در list را می‌گیرد.

for arg in "$var1" "$var2" "$var3" ... "$varN"  
#  در دور اول حلقه، ‎arg = $var1‎
#  در دور دوم حلقه، arg = $var2	    
#  در دور سوم حلقه، arg = $var3	    
# ...
#  در نوبت N‎ام حلقه، arg = $varN

# برای پیش‌گیری از تفکیک کلمه احتمالی، شناسه‌ها در ‎[list]‎ نقل‌قولی شده‌اند.

شناسه list می‌تواند شامل کاراکترهای عام باشد.

اگر do در همان سطر for باشد، وجود یک سمی‌کالن بعد از list لازم است.

for arg in [list] ; do

مثال ‎11-1‎. حلقه‌های ساده for

#!/bin/bash
#

for planet in Mercury Venus Earth Mars Jupiter Saturn Uranus Neptune Pluto
do
  echo $planet  #
done

echo; echo

for planet in "Mercury Venus Earth Mars Jupiter Saturn Uranus Neptune Pluto"
    #                                   
    #  کل ‎list‎ محصور شده در نقل‌قول‌ها، یک متغیر منفرد ایجاد می‌کند.
    #                  
do
  echo $planet
done

echo; echo "Whoops! Pluto is no longer a planet!"

exit 0

هر عضو ‎[list]‎ می‌تواند شامل پارامترهای متعددی باشد . این مطلب موقع پردازش پارامترهای گروهی مفید است. در چنین مواردی، برای تجزیه اجباری هر عضو ‎[list]‎ و تخصیص هر جزء تشکیل‌دهنده به پارامترهای مکانی، فرمان set را به کار ببرید ( مثال ‎15-16‎ را ببینید).

مثال ‎11-2‎. حلقه for با دو پارامتر در هرعضوِِ ‎[list]‎

#!/bin/bash
#                                    

#            

for planet in "Mercury 36" "Venus 67" "Earth 93"  "Mars 142" "Jupiter 483"
do
  set -- $planet     #        متغیر ‎"planet"‎ را تجزیه نموده، و
                     #+    
  #  کاربرد ‎"--"‎ در صورتیکه ‎$planet‎ تهی باشد یا با یک خط تیره
  #+   

  # 
  #+ 
  #           آرایه است، به این شکل:   ‎original_params=("$@")‎

  echo "$1		$2,000,000 miles from the sun"
  #       پیوست نمودن صفرها با پارامتر ‎$2‎   ‏ |-دو تا ‎tab‎ -|
done

#                  (با تشکر از ‎S.C.‎ به خاطر شفاف‌سازی بیشتر.)

exit 0

در یک حلقه for ممکن است یک متغیر [list] را تامین نماید.

مثال ‎11-3‎.‏ ‎Fileinfo‎: عمل کردن روی فهرستی از فایلها که محتوای یک متغیر هستند

#!/bin/bash
#

FILES="/usr/sbin/accept
/usr/sbin/pwck
/usr/sbin/chroot
/usr/bin/fakefile
/sbin/badblocks
/sbin/ypbind"       #                  
                    #    قرار دادن یک فایل ساختگی ‎/usr/bin/fakefile‎ بین آنها.

echo

for file in $FILES
do

  if [ ! -e "$file" ]                        # 
  then
    echo "$file does not exist."; echo
    continue                                 #        
   fi

  ls -l $file | awk '{ print $8 "         file size: " $5 }'  # 
  whatis `basename $file`                    #                 
  # توجه نمایید که برای این منظور لازم است بانک اطلاعات ‎‎whatis‎  آماده شده باشد.
  # برای انجام این کار، به عنوان کاربر ارشد ‎/usr/bin/makewhatis‎ را اجرا کنید.
  echo
done  

exit 0

در یک حلقه for ممکن است ‎[list]‎ پارامتری بشود.

مثال ‎11-4‎. عمل نمودن روی یک لیست فایل پارامتری شده

#!/bin/bash

filename="*txt"

for file in $filename
do
 echo "Contents of $file"
 echo "---"
 cat "$file"
 echo
done

در صورتیکه ‎[list]‎ در یک حلقه for شامل کاراکترهای عام (* و ?) مورد استفاده در بسط نام فایل باشد، آنوقت ‎globbing‎ صورت می‌گیرد.

مثال ‎11-5‎. عمل کردن روی فایلها با یک حلقه for

#!/bin/bash
#اسکریپت ‎list-glob.sh‎: تولید ‎[list]‎ در یک حلقه for با کاربرد ‎globbing‎ ...
#

echo

for file in *
#
#+     
do
  ls -l "$file"  # تمام فایلها در ‎$PWD‎ (دایرکتوری جاری) را لیست می‌کند.
  #         به یاد بیاورید که کاراکتر ‎"*"‎ با هر نام فایلی مطابقت می‌کند،
  #+                 اما در ‎"globbing"‎ با فایلهای نقطه‌ای منطبق نمی‌شود.

  #      
  #               برای پرهیز از این مورد، گزینه ‎nullglob‎ را تنظیم کنید.
  #+                                  به این شکل:    ‎shopt -s nullglob‎
  #                                                    با تشکر از ‎S.C.‎
done

echo; echo

for file in [jx]*
do
  rm -f $file   #فقط فایلهایی در ‎$PWD‎ را که با ‎j‎ یا ‎x‎ شروع شوند حذف می‌کند.
  echo "Removed file \"$file\"".
done

echo

exit 0

از قلم انداختن بخش ‎in [list]‎ از یک حلقه for باعث می‌شود حلقه روی ‎$@‎ یعنی پارامترهای مکانی عمل نماید. یک توضیح ماهرانه مشروحِ این مطلب، مثال ‎A-15‎ است. همچنین مثال ‎15-17‎ را ملاحظه نمایید.

مثال ‎11-6‎. فقدان ‎in [list]‎ در یک حلقه for

#!/bin/bash

#

for a
do
 echo -n "$a "
done

#   ‎'in list'‎ غایب است، بنابراین حلقه روی ‎'$@'‎ عمل می‌کند
#+            (لیست شناسه‌های خط فرمان، شامل فضای سفید).

echo

exit 0

استفاده از جایگزینی فرمان برای تولید ‎[list]‎ در یک حلقه for امکان‌پذیر است. همچنین مثال ‎16-54‎‏، مثال ‎11-11‎ و مثال ‎16-48‎ را ببینید.

مثال ‎11-7‎. تولید ‎[list]‎ در یک حلقه for با جایگزینی فرمان

 #!/bin/bash
# اسکریپت ‎for-loopcmd.sh‎: حلقه ‎for‎ با ‎[list]‎ تولید شده توسط جایگزینی فرمان

NUMBERS="9 7 3 8 37.53"

for number in `echo $NUMBERS`     #      برای ‎number‎ در لیست ‎9 7 3 8 37.53‎
do
  echo -n "$number "
done

echo 
exit 0

این هم یک مثال تا اندازه‌ای پیچیده‌ترِ استفاده از جایگزینی فرمان برای تولید ‎[list]‎.

مثال ‎11-8‎. یک جایگزینی grep برای فایلهای باینری

#!/bin/bash
# اسکریپت ‎bin-grep.sh‎: رشته‌های منطبق را در یک فایل باینری جایگزین می‌کند.

#            یک جایگزینی grep برای فایلهای باینری.
#                        مشابه اثر فرمان ‎"grep -a"‎

E_BADARGS=65
E_NOFILE=66

if [ $# -ne 2 ]
then
  echo "Usage: `basename $0` search_string filename"
  exit $E_BADARGS
fi

if [ ! -f "$2" ]
then
  echo "File \"$2\" does not exist."
  exit $E_NOFILE
fi  


IFS=$'\012'       # طبق پیشنهاد ‎Anton Filippov‎
                  #    عبارت بود از:  ‎IFS="\n"‎
for word in $( strings "$2" | grep "$1" )
#  فرمان strings رشته‌ها در فایل باینری را لیست می‌کند. سپس خروجی
#  به ‎grep‎ لوله‌کشی می‌شود، که برای رشته مورد نظر معاینه‌اش می‌کند.
do
  echo $word
done

#  همچنانکه ‎S.C.‎ اشاره می‌کند، سطرهای ‎23 - 30‎ می‌توانست با شکل ساده‌تر
#        ‎strings "$2" | grep "$1" | tr -s "$IFS" '[\n*]'‎ تعویض بشود.


#   برای به کار بردن این اسکریپت موردی مانند
#+ ‎"./bin-grep.sh mem /bin/ls"‎ را امتحان کنید    

exit 0

بیشتر در همین مورد.

مثال ‎11-9‎. لیست کردن تمام کاربران سیستم

#!/bin/bash
#

PASSWORD_FILE=/etc/passwd
n=1           #

for name in $(awk 'BEGIN{FS=":"}{print $1}' < "$PASSWORD_FILE" )
#                         ‎:‎ جداکننده فیلد است       ^^^^^^
#                                 چاپ فیلد اول    ^^^^^^^^
#
do
  echo "USER #$n = $name"
  let "n += 1"
done  


#
#
#
# ...
#

exit $?

#                           
#  ----------
#    چطور است که یک کاربر معمولی، یا اسکریپت اجرا شده توسط او می‌تواند فایل
#+ ‎/etc/passwd‎ را بخواند؟ (اشاره: مجوزهای فایل ‎/etc/passwd‎ را بررسی کنید.)
#                          آیا این یک حفره امنیتی است؟ چرا هست یا چرا نیست؟

بازهم یک مثال دیگر از ‎[list]‎ حاصل از جایگزینی فرمان.

مثال ‎11-10‎. کنترل تمام فایلهای باینری در یک دایرکتوری برای تعیین هویت نویسنده

#!/bin/bash
#
#

directory=/usr/bin/
fstring="Free Software Foundation"  
   #     

for file in $( find $directory -type f -name '*' | sort )
do
  strings -f $file | grep "$fstring" | sed -e "s%$directory%%"
  #  لازم است که در عبارت sed جداکننده‌های / معمولی تعویض بشوند،
  #+   زیرا / یکی از کاراکترهایی است که فیلتر می‌گردد، اگر این
  #+ 
done  

exit $?

#  تمرین (آسان)‏:
#  ---------------
#اسکریپت را جهت قبول پارامترهای خط فرمان برای ‎$directory‎ و ‎$fstring‎ تغییر بدهید.

آخرین مثال از ‎[list]‎ و جایگزینی فرمان، اما این دفعه «فرمان» یک تابع است.

generate_list ()
{
  echo "one two three"
}

for word in $(generate_list)  # برای آنکه ‎word‎ خروجی تابع را اخذ کند.
do
  echo "$word"
done

#
#
#

خروجی یک حلقه for ممکن است به فرمان یا فرمانهایی لوله‌کشی بشود.

مثال ‎11-11‎. لیست نمودن پیوندهای نمادین در یک دایرکتوری

#!/bin/bash
#   ‎symlinks.sh‎: پیوندهای نمادین در یک دایرکتوری را لیست می‌کند.


directory=${1-`pwd`}
#
#                                     
#
# ARGS=1                        #
#
# if [ $# -ne "$ARGS" ]         #         
# then
#   directory=`pwd`             #           
# else
#   directory=$1
# fi
#

echo "symbolic links in directory \"$directory\""

for file in "$( find $directory -type l )"   #  ‎-type l‎ یعنی پیوندهای نمادین.  
do
  echo "$file"
done | sort                                  #
#
#+     چون، خروجی فرمان  find به یک کلمه منفرد بسط می‌یابد.
# 

#   به طوری که ‎Dominik 'Aeneas' Schnitzer‎ اشاره می‌کند، با
#+   کوتاهی در نقل‌قول نمودن ‎$( find $directory -type l )‎
#+     

exit 0


# --------------------------------------------------------
#  ‎Jean Helou‎ جایگزینی مورد زیر را پیشنهاد می‌دهد:

echo "symbolic links in directory \"$directory\""
# تهیه پشتیبان از ‎IFS‎ فعلی. شخص نمی‌تواند همیشه خیلی هشیار باشد.
OLDIFS=$IFS
IFS=:

for file in $(find $directory -type l -printf "%p$IFS")
do          #
       echo "$file"
       done|sort

#  و ‎James "Mike" Conley‎ ویرایش کد ‎Helou‎ را بدین طریق پیشنهاد می‌کند:

OLDIFS=$IFS
IFS=''      #  IFS تهی یعنی کلمه‌ خُرد نمی‌شود
for file in $( find $directory -type l )
do
  echo $file
  done | sort

#
# 
#      

همان طور که بهسازی جزئی زیر برای مثال قبل نشان می‌دهد، stdout یک حلقه می‌تواند به یک فایل تغییر مسیر داده شود.

مثال ‎11-12‎. پیوندهای نمادین در یک دایرکتوری، ذخیره شده در یک فایل

#!/bin/bash
# ‎symlinks.sh‎: پیوندهای نمادین در یک دایرکتوری را لیست می‌کند.

OUTFILE=symlinks.list                         #

directory=${1-`pwd`}
#


echo "symbolic links in directory \"$directory\"" > "$OUTFILE"
echo "---------------------------" >> "$OUTFILE"

for file in "$( find $directory -type l )"    # ‎-type l‎ یعنی پیوندهای نمادین
do
  echo "$file"
done | sort >> "$OUTFILE"                    #        
#

#

exit $?

یک ترکیب دستوری جایگزین برای حلقه for وجود دارد که برای برنامه‌نویسان ‎C‎ خیلی آشنا است. این ترکیب به پرانتزهای دوگانه نیاز دارد.

مثال ‎11-13‎. یک حلقه for سبکِ ‎C‎

#!/bin/bash
# چندین روش برای شمارش تا ‎10‎

echo

#
for a in 1 2 3 4 5 6 7 8 9 10
do
  echo -n "$a "
done  

echo; echo

#

# استفاده از ‎"seq"‎ ...
for a in `seq 10`
do
  echo -n "$a "
done  

echo; echo

#

#
# در ‎Bash‎ نگارش ‎3+‎.
for a in {1..10}
do
  echo -n "$a "
done  

echo; echo

#

# اکنون بیایید همان کار را باترکیب ‎C-مانند انجام بدهیم.

LIMIT=10

for ((a=1; a <= LIMIT ; a++))      #  پرانتزهای دوگانه و ‎LIMIT‎ بدون ‎$‎
do
  echo -n "$a "
done                               #  یک ساختار اقتباس شده از ‎ksh93‎.

echo; echo

#

# بیایید از عملگر کامای C برای افزایش دو متغیر به طور همزمان، استفاده نماییم.

for ((a=1, b=1; a <= LIMIT ; a++, b++))
do  #
  echo -n "$a-$b "
done

echo; echo

exit 0

همچنین مثال ‎27-16‎، مثال ‎27-17‎، و مثال ‎A-6‎ را ببینید.

---

اکنون، یک حلقه for مورد استفاده در یک مضمون «واقعی».

مثال ‎11-14‎. کاربرد efax در وضعیت دسته‌ای

#!/bin/bash
# ‎Fax‎ کردن (باید بسته ‎efax‎ نصب شده باشد).

EXPECTED_ARGS=2
E_BADARGS=85
MODEM_PORT="/dev/ttyS2"   #
#             پورت پیش‌فرض کارت مودم ‎PCMCIA‎

if [ $# -ne $EXPECTED_ARGS ]
# 
then
   echo "Usage: `basename $0` phone# text-file"
   exit $E_BADARGS
fi


if [ ! -f "$2" ]
then
  echo "File $2 is not a text file."
  #
  exit $E_BADARGS
fi
  

fax make $2               #ایجاد فایلهای قالب‌بندی شده ‎fax‎ از فایلهای متن.

for file in $(ls $2.0*)   #               به هم پیوستن فایلهای تبدیل شده.
#        در لیست متغیر از کاراکتر عام («جانشینی» نام فایل) استفاده می‌کند.
do
  fil="$fil $file"
done  

efax -d "$MODEM_PORT"  -t "T$1" $fil    #عاقبت، انجام کار.
#       آزمایش افزودن ‎-o1‎ در صورتی که سطر فوق ناموفق گردد.


#  به طوریکه ‎S.C.‎ اشاره می‌کند، حلقه ‎for‎ می‌تواند با استفاده
#       از ‎efax -d /dev/ttyS2 -o1 -t "T$1" $2.0*‎ حذف بشود.
#+                                اما واقعاً آموزنده نیست.

exit $?   #‎efax‎ پیغام‌های تشخیصی نیز به خروجی استاندارد ارسال می‌کند.

کلیدواژه‌های do و done بلوک فرمانِ حلقه for را مشخص می‌کنند. اگرچه، ممکن است در برخی مضمون‌ها، به واسطه قاب‌بندی قطعه‌فرمان در داخل ابروها، این کلمه‌ها ذکر نگردند.
for((n=1; n<=10; n++)) 
# ‎do‎ نیست!
{
  echo -n "* $n *"
}
# ‎done‎ نیست!


#                   
#
# و ‎echo $?‎ مقدار ‎0‎ را برگشت می‌دهد، بنابراین ‎Bash‎ خطا گزارش نمی‌کند.


echo


# اما، توجه کنید که در یک حلقه کلاسیک ‎for‎ به شکل ‎for n in [list] ...‎
#+                         

for n in 1 2 3
{  echo -n "$n "; }
#


# با تشکر از ‎YongYe‎ برای توضیح این مورد.


while

این ساختار، یک شرط را در ابتدای یک حلقه بررسی می‌کند، و تا وقتی که آن شرط صحیح باشد (یک وضعیت خروج 0 برگشت بدهد) حلقه را حفظ می‌کند. در مقایسه با حلقه for، یک حلقه while در وضعیت‌هایی که تعداد تکرار از قبل شناخته شده نیست مورد استفاده می‌یابد.

while [ condition ]
do
 command(s)...
done

ساختار براکت در یک حلقه while چیزی غیراز دوست قدیمی ما، براکت‌های تست مورد استفاده در یک بررسی ‎if/then‎ نیست. در حقیقت، یک حلقه while به طور مجاز می‌تواند ساختار براکت‌های دوتایی ‎(while [[ condition ]])‎ کارآمدتر را استفاده کند.

مانند همان حالت حلقه‌های for، قرار دادن do در همان سطر بررسی شرط به یک سمی‌کالن نیاز دارد.

while [ condition ] ; do

توجه نمایید که براکت‌های تست در یک حلقه while اجباری نیستند. برای مثال، ساختار getopts را ببینید.

مثال ‎11-15‎. حلقه ساده while

#!/bin/bash

var0=0
LIMIT=10

while [ "$var0" -lt "$LIMIT" ]
#
#
do
  echo -n "$var0 "        # ‎-n‎ سطر جدید را موقوف می‌کند.
  #         فاصله، برای جدا کردن اعداد چاپ شده.

  var0=`expr $var0 + 1`   #     ‎var0=$(($var0+1))‎ نیز کار می‌کند.
                          #     ‎var0=$((var0 + 1))‎ هم کار می‌کند.
                          #      ‎let "var0 += 1"‎ نیز کار می‌کند.
done                      #

echo

exit 0

مثال ‎11-16‎. یک حلقه while دیگر

#!/bin/bash

echo
while [ "$var1" != "end" ]     #  معادل است با ‎while test "$var1" != "end"‎
do
  echo "Input variable #1 (end to exit) "
  read var1                    #   از ‎read $var1‎ استفاده نشده (چرا؟)‏.
  echo "variable #1 = $var1"   #    به علت وجود # نقل‌قول‌ها لازم هستند.
  #   اگر ورودی end باشد، اینجا آن را نشان می‌دهد.
  #
  echo
done  

exit 0

یک حلقه while ممکن است دارای چند شرط باشد. فقط شرط انتهایی تعیین می‌کند که حلقه چه وقت خاتمه یابد. اگر چه، این یک تفاوت ناچیز را ایجاب می‌نماید.

مثال ‎11-17‎. حلقه while با چند شرط

#!/bin/bash

var1=unset
previous=$var1

while echo "previous-variable = $previous"
      echo
      previous=$var1
      [ "$var1" != end ]      #         کسب اطلاع از آنچه ‎$var1‎ قبلاً بوده.
      # چهار وضعیت در ‎while‎، اما فقط مورد انتهایی، حلقه را کنترل می‌کند.
      #                         
do
echo "Input variable #1 (end to exit) "
  read var1
  echo "variable #1 = $var1"
done  

#
#                         

exit 0

همچون حلقه for، یک حلقه while نیز می‌تواند با استفاده از ساختار پرانتزهای دوتایی، ترکیب ‎C-style‎ را به کار ببرد ( مثال ‎8-5‎ را هم ببینید).

مثال ‎11-18‎. ترکیب ‎C-style‎ در یک حلقه while

#!/bin/bash
#  شمارش تا ‎10‎ در یک حلقه while

LIMIT=10                 #   
a=1

while [ "$a" -le $LIMIT ]
do
  echo -n "$a "
  let "a+=1"
done                     #

echo; echo

# +=================================================================+

#  اکنون، با ترکیب C-مانند تکرار خواهیم نمود.

((a = 1))                 # 
#  پرانتزهای دوتایی، همچون در ‎C درج فاصله را هنگام تنظیم متغیر اجازه می‌دهند‎.

while (( a <= LIMIT ))   # پرانتزهای دوتایی و عدم استفاده از ‎$‎ مقدم متغیرها
do                       
  echo -n "$a "
  ((a += 1))              #  معادل با ‎let "a+=1"‎
                          #
  # پرانتزهای دوتایی افزایش یک متغیر با ترکیب دستوری مانند ‎C‎ را مجاز می‌سازند.
done

echo

#                  برنامه‌نویسان ‎C‎ و ‎Java‎ می‌توانند در ‎Bash‎ احساس راحتی نمایند.

exit 0

یک حلقه while می‌تواند داخل براکت‌های تست خود، یک تابع را فراخوانی کند.

t=0

condition ()
{
  ((t++))

  if [ $t -lt 5 ]
  then
    return 0  #
  else
    return 1  #
  fi
}

while condition
#
#     احضار تابع -- چهار بار تکرار حلقه.
do
  echo "Still going: t = $t"
done

#
#
#
#

توسط بهم وصل کردن قدرت فرمان read با یک حلقه while، ساختار سودمند while read مفید برای خواندن و تجزیه فایلها را به دست می‌آوریم.

cat $filename |   #                        
while read line   #
do
  ...
done

#

  while read value         # 
  do
    rt=$(echo "scale=$SC; $rt + $value" | bc)
    (( ct++ ))
  done

  am=$(echo "scale=$SC; $rt / $ct" | bc)

  echo $am; return $ct     #   
  #  توجه: این ترفند کوچک در صورتیکه ‎$ct‎ بزرگتر از ‎255‎ باشد کار 
  #  نمی‌کند! برای کار کردن با یک تعداد بزرگتری از واحدهای داده،
  #+       به سادگی ‎"return $ct"‎ بالا را به حالت توضیح درآورید.
} <"$datafile"             #                


یک حلقه while ممکن است ورودی استانداردش را توسط یک ‎<‎ در انتهایش به یک فایل تغییر مسیر داده باشد.

یک حلقه while ممکن است ورودی استانداردش را توسط یک لوله فراهم کرده باشد.


until

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

until [ condition-is-true ]
do
 command(s)...
done

توجه نمایید که حلقه until شرط خاتمه دادن را در بالای حلقه بررسی می‌کند، متفاوت با ساختار مشابه آن در برخی زبانهای برنامه‌نویسی است.

همچون در مورد حلقه‌های for، قرار دادن do در همان سطرِ شرط نیازمند یک سمی‌کالن است.

until [ condition-is-true ] ; do

مثال ‎11-19‎. حلقه until

#!/bin/bash

END_CONDITION=end

until [ "$var1" = "$END_CONDITION" ]
#
do
  echo "Input variable #1 "
  echo "($END_CONDITION to exit)"
  read var1
  echo "variable #1 = $var1"
  echo
done  



#    همچون همراه با حلقه‌های ‎"for"‎ و ‎"while"‎ یک حلقه
#+ ‎"until"‎ نیز ساختارهای تست C-مانند را اجازه می‌دهد.

LIMIT=10
var=0

until (( var > LIMIT ))
do  #نه براکت‌ها، نه ‎$‎ پیشوندی متغیرها.
  echo -n "$var "
  (( var++ ))
done    #


exit 0

چطور بین یک حلقه for یا یک حلقه while یا حلقه until انتخاب کنیم؟ در C، به طور نمونه یک حلقه for را موقعی به کار می‌برید که تعداد تکرار حلقه از قبل معلوم است. اما با Bash وضعیت نامعلوم‌تر است. حلقه for در Bash به طور آزادانه‌تری ساخته شده و بیشتر از معادلش در سایر زبانها انعطاف‌پذیر است. بنابراین، با خیال راحت هر نوع حلقه‌ای را که به ساده‌ترین روش کار را انجام می‌دهد استفاده کنید.

یادداشت‌ها

[1]

تکرار: اجرای تکراری یک فرمان یا گروهی از فرمانها، اغلب -- اما نه همیشه، در حالیکه یک شرط مفروض برقرار است، یا تا وقتی یک شرط مفروض برقرار بشود.