Наши партнеры








Книги по Linux (с отзывами читателей)

Библиотека сайта rus-linux.net

На главную -> MyLDP -> Электронные книги по ОС Linux
Руководство по Bash для начинающих
Назад Глава 9: Повторяющиеся задачи Вперед

Цикл типа while

Что это такое?

Конструкция while позволяет повторно выполнять список команд до тех пор, пока команда, проверяемая в while, будет возвращать код успешного выполнения (код возврата будет равен нулю). Синтаксис следующий:

while CONTROL-COMMAND; do CONSEQUENT-COMMANDS; done 

Командой CONTROL-COMMAND может быть любая команда (команды), которая в случае успеха и неудачи может выдавать различные коды возврата. Командами CONSEQUENT-COMMANDS могут быть любые программы, скрипты или конструкции, используемые в командной оболочке.

Как только команда CONTROL-COMMAND выдаст код неудачного исполнения, происходит выход из цикла. В скрипте выполняется команда, следующая за done.

Кодом возврата является код возврата последней команды из CONSEQUENT-COMMANDS, или ноль, если ни одна из команд не была выполнена.

Примеры

Простой пример использования while

Ниже пример для нетерпеливых:

#!/bin/bash

# This script opens 4 terminal windows.

i="0"

while [ $i -lt 4 ]
do
xterm &
i=$[$i+1]
done

Вложенные циклы while

Пример, приведенный ниже, был написан для копирования фотографий, сделанных веб-камерой, в каталог веб-сервера. Фотографии делаются каждые пять минут. Каждый час создается новый директорий, в котором будут храниться фотографии, сделанные в течение этого часа. Каждый день создается новый директорий, в котором находятся 24 поддиректория. Скрипт запускается в фоновом режиме.

#!/bin/bash

# This script copies files from my homedirectory into the webserver directory.
# (use scp and SSH keys for a remote directory)
# A new directory is created every hour.

PICSDIR=/home/carol/pics
WEBDIR=/var/www/carol/webcam

while true; do 
        DATE=`date +%Y%m%d`
        HOUR=`date +%H`
        mkdir $WEBDIR/"$DATE"
        
        while [ $HOUR -ne "00" ]; do 
                DESTDIR=$WEBDIR/"$DATE"/"$HOUR"
                mkdir "$DESTDIR"
                mv $PICDIR/*.jpg "$DESTDIR"/
                sleep 3600
                HOUR=`date +%H`
        done
done

Обратите внимание на инструкции true. Это означает: выполнение продолжается до тех пор, пока цикл не будет прерван принудительно (с помощью kill или Ctrl+C).

Следующий небольшой скрипт можно использовать для имитационных испытаний; он генерирует файлы:

#!/bin/bash

# This generates a file every 5 minutes

while true; do
touch pic-`date +%s`.jpg
sleep 300
done

Обратите внимание, как команда date используется для создания всех имен файлов и директориев. Подробности смотрите на странице man.

 Используйте систему

Предыдущий пример создан только в демонстрационных целях. Регулярные проверки можно легко выполнять с помощью системного средства cron. Не забудьте перенаправить выходной поток и поток ошибок, когда используете скрипты, выполняемые из вашей таблицы crontab!

Использование клавиатуры для управления циклом while

Следующий цикл может быть прерван пользователем, когда он вводит последовательность Ctrl+C:

#!/bin/bash

# This script provides wisdom

FORTUNE=/usr/games/fortune

while true; do
echo "On which topic do you want advice?"
cat < topics
politics
startrek
kernelnewbies
sports
bofh-excuses
magic
love
literature
drugs
education
topics

echo
echo -n "Make your choice: "
read topic
echo
echo "Free advice on the topic of $topic: "
echo
$FORTUNE $topic
echo

done

Здесь для представления вариантов, которые может выбрать пользователь, применяется встраиваемый документ (here document). И здесь опять проверка true позволяет бесконечно повторять команды из списка CONSEQUENT-COMMANDS.

Вычисление среднего значения

Этот скрипт вычисляет среднее всех значений, введенных пользователем, которые проверяются перед обработкой: если введенное значение не попадает в заданный диапазон, то выдается сообщение об ошибке. Если нажимается клавиша q, то происходит выход из цикла:

#!/bin/bash

# Calculate the average of a series of numbers.

SCORE="0"
AVERAGE="0"
SUM="0"
NUM="0"

while true; do

  echo -n "Enter your score [0-100%] ('q' for quit): "; read SCORE;

  if (("$SCORE" < "0"))  || (("$SCORE" > "100")); then
    echo "Be serious.  Common, try again: "
  elif [ "$SCORE" == "q" ]; then
    echo "Average rating: $AVERAGE%."
    break
  else
    SUM=$[$SUM + $SCORE]
    NUM=$[$NUM + 1]
    AVERAGE=$[$SUM / $NUM]
  fi

done

echo "Exiting."

Обратите внимание, что чтобы можно было выполнять арифметические действия, переменные, используемые в последних строках, указываются без кавычек.


Предыдущий раздел: Оглавление Следующий раздел:
Цикл типа for   Цикл типа until