The OpenNET Project / Index page

[ новости /+++ | форум | wiki | теги | ]

Поиск:  Каталог документации

3.8. Loops

for (in)

This is the basic looping construct. It differs significantly from its C counterpart.

for [arg] in [list]
do
═command...
done

Note that list may contain wild cards.

Note further that if do is on same line as for, there needs to be a semicolon before list.

for [arg] in [list] ; do

Example 3-24. Simple for loops

#!/bin/bash

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

echo

# Entire 'list' enclosed in quotes creates a single variable.
for planet in "Mercury Venus Earth Mars Jupiter Saturn Uranus Neptune Pluto"
do
  echo $planet
done

exit 0

Omitting the in [list] part of a for loop causes the loop to operate on $#, the list of arguments given on the command line to the script.

Example 3-25. Missing in [list] in a for loop

#!/bin/bash

# Invoke both with and without arguments,
# and see what happens.

for a
do
 echo $a
done

# 'in list' missing, therefore
# operates on '$#'
# (command-line argument list)

exit 0

Example 3-26. Using efax in batch mode

#!/bin/bash

if [ $# -ne 2 ]
# Check for proper no. of command line args.
then
   echo "Usage: `basename $0` phone# text-file"
   exit 1
fi


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

# Create fax formatted files from text files.
fax make $2

for file in $(ls $2.0*)
# Concatenate the converted files.
# Uses wild card in variable list.
do
  fil="$fil $file"
done  

# Do the work.
efax -d /dev/ttyS3 -o1 -t "T$1" $fil

exit 0
while

This construct tests for a condition at the top of a loop, and keeps looping as long as that condition is true.

while [condition]
do
═command...
done

As is the case with for/in loops, placing the do on the same line as the condition test requires a semicolon.

while [condition] ; do

Note that certain specialized while loops, as, for example, a getopts construct, deviate somewhat from the standard template given here.

Example 3-27. Simple while loop

#!/bin/bash

var0=0

while [ "$var0" -lt 10 ]
do
  echo -n "$var0 "
  # -n suppresses newline.
  var0=`expr $var0 + 1`
  # var0=$(($var0+1)) also works.
done

echo

exit 0

Example 3-28. Another while loop

#!/bin/bash

while [ "$var1" != end ]
do
  echo "Input variable #1 "
  echo "(end to exit)"
  read var1
  # It's not 'read $var1'
  # because value of var1 is set.
  echo "variable #1 = $var1"
  # Need quotes because of #
done  

# Note: Echoes 'end' because
# termination condition
# tested for at top of loop.

exit 0
until

This construct tests for a condition at the top of a loop, and keeps looping as long as that condition is false (opposite of while loop).

until [condition-is-true]
do
═command...
done

Note that an until loop tests for the terminating condition at the top of the loop, differing from a similar construct in some programming languages.

As is the case with for/in loops, placing the do on the same line as the condition test requires a semicolon.

until [condition-is-true] ; do

Example 3-29. until loop

#!/bin/bash

until [ "$var1" = end ]
# Tests condition at top of loop.
do
  echo "Input variable #1 "
  echo "(end to exit)"
  read var1
  echo "variable #1 = $var1"
done  

exit 0
break, continue

The break and continue loop control commands correspond exactly to their counterparts in other programming languages. The break command terminates the loop (breaks out of it), while continue causes a jump to the next iteration of the loop, skipping all the remaining commands in that particular loop cycle.

Example 3-30. Effects of break and continue in a loop

#!/bin/bash

echo
echo Printing Numbers 1 through 20.

a=0

while [ $a -le 19 ]

do
 a=$(($a+1))

 if [ $a -eq 3 ] || [ $a -eq 11 ]
 # Excludes 3 and 11
 then
   continue
   # Skip rest of this particular loop iteration.
 fi

 echo -n "$a "
done 

# Exercise for reader:
# Why does loop print up to 20?

echo
echo

echo Printing Numbers 1 through 20, but something happens after 2.

##################################################################

# Same loop, but substituting 'break' for 'continue'.

a=0

while [ $a -le 19 ]
do
 a=$(($a+1))

 if [ $a -gt 2 ]
 then
   break
   # Skip entire rest of loop.
 fi

 echo -n "$a "
done

echo
echo

exit 0
case (in) / esac

The case construct is the shell equivalent of switch in C/C++. It permits branching to one of a number of code blocks, depending on condition tests. It serves as a kind of shorthand for multiple if/then/else statements and is an appropriate tool for creating menus.

case "$variable" in

═"$condition1" )
command...
═;;

═"$condition2" )
command...
═;;

esac

Note:

  • Quoting the variables is recommended.

  • Each test line ends with a left paren ).

  • Each condition block ends with a double semicolon ;;.

  • The entire case block terminates with an esac (case spelled backwards).

Example 3-31. Using case

#!/bin/bash

echo
echo "Hit a key, then hit return."
read Keypress

case "$Keypress" in
  [a-z]   ) echo "Lowercase letter";;
  [A-Z]   ) echo "Uppercase letter";;
  [0-9]   ) echo "Digit";;
  *       ) echo "Punctuation, whitespace, or other";;
esac
# Allows ranges of characters in [square brackets].

exit 0

Example 3-32. Creating menus using case

#!/bin/bash

# Crude rolodex-type database

clear
# Clear the screen.

echo "          Contact List"
echo "          ------- ----"
echo "Choose one of the following persons:" 
echo
echo "[E]vans, Roland"
echo "[J]ones, Mildred"
echo "[Smith], Julie"
echo "[Z]ane, Morris"
echo

read person

case "$person" in
# Note variable is quoted.

  "E" | "e" )
  # Accept upper or lowercase input.
  echo
  echo "Roland Evans"
  echo "4321 Floppy Dr."
  echo "Hardscrabble, CO 80753"
  echo "(303) 734-9874"
  echo "(303) 734-9892 fax"
  echo "revans@zzy.net"
  echo "Business partner & old friend"
  ;;
# Note double semicolon to terminate
# each option.

  "J" | "j" )
  echo
  echo "Mildred Jones"
  echo "249 E. 7th St., Apt. 19"
  echo "New York, NY 10009"
  echo "(212) 533-2814"
  echo "(212) 533-9972 fax"
  echo "milliej@loisaida.com"
  echo "Girlfriend"
  echo "Birthday: Feb. 11"
  ;;

# Add info for Smith & Zane later.

          * )
   # Default option.	  
   echo
   echo "Not yet in database."
  ;;   


esac

echo

exit 0
select

The select construct, adopted from the Korn Shell, is yet another tool for building menus.

select variable [in list]
do
command...
═break
done

This prompts the user to enter one of the choices presented in the variable list. Note that select uses the PS3 prompt (#? ) by default, but that this may be changed.

Example 3-33. Creating menus using select

#!/bin/bash

PS3='Choose your favorite vegetable: '
# Sets the prompt string.

echo

select vegetable in "beans" "carrots" "potatoes" "onions" "rutabagas"
do
  echo
  echo "Your favorite veggie is $vegetable."
  echo "Yuck!"
  echo
  break
  # if no 'break' here, keeps looping forever.
done

exit 0

If in list is omitted, then select uses the list of command line arguments ($@) passed to the script or to the function in which the select construct is embedded. (Compare this to the behavior of a

for variable [in list]

construct with the in list omitted.)

Example 3-34. Creating menus using select in a function

#!/bin/bash

PS3='Choose your favorite vegetable: '

echo

choice_of()
{
select vegetable
# [in list] omitted, so 'select' uses arguments passed to function.
do
  echo
  echo "Your favorite veggie is $vegetable."
  echo "Yuck!"
  echo
  break
done
}

choice_of beans rice carrots radishes tomatoes spinach
#         $1    $2   $3      $4       $5       $6
#         passed to choice_of() function

exit 0



Спонсоры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2022 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру