Библиотека сайта rus-linux.net
Руководство по 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 |