# Команда "continue N" передает управление в начало внешнего цикла, отстоящего от текущего на N уровней.
for outer in I II III IV V # внешний цикл
do
echo; echo -n "Группа $outer: "
for inner in 1 2 3 4 5 6 7 8 9 10 # вложенный цикл
do
if [ "$inner" -eq 7 ]
then
continue 2 # Передача управления в начало цикла 2-го уровня.
# попробуйте убрать параметр 2 команды "continue"
fi
echo -n "$inner " # 8 9 10 никогда не будут напечатаны.
done
done
echo; echo
# Упражнение:
# Подумайте, где реально можно использовать "continue N" в сценариях.
exit 0
Пример 10-23. Живой пример использования "continue N"
# Albert Reiner привел пример использования "continue N":
# ---------------------------------------------------------
# Допустим, у меня есть большое количество задач, обрабатывающие некоторые данные,
#+ которые хранятся в некоторых файлах, с именами, задаваемыми по шаблону,
#+ в заданном каталоге.
#+ Есть несколько машин, которым открыт доступ к этому каталогу
#+ и я хочу распределить обработку информации между машинами.
#+ тогда я обычно для каждой машины пишу нечто подобное:
while true
do
for n in .iso.*
do
[ "$n" = ".iso.opts" ] && continue
beta=${n#.iso.}
[ -r .Iso.$beta ] && continue
[ -r .lock.$beta ] && sleep 10 && continue
lockfile -r0 .lock.$beta || continue
echo -n "$beta: " `date`
run-isotherm $beta
date
ls -alF .Iso.$beta
[ -r .Iso.$beta ] && rm -f .lock.$beta
continue 2
done
break
done
# Конкретная реализация цикла, особенно sleep N, зависит от конкретных применений,
#+ но в общем случае он строится по такой схеме:
while true
do
for job in {шаблон}
do
{файл уже обработан или обрабатывается} && continue
{пометить файл как обрабатываемый, обработать, пометить как обработанный}
continue 2
done
break # Или что нибудь подобное `sleep 600', чтобы избежать завершения.
done
# Этот сценарий завершит работу после того как все данные будут обработаны
#+ (включая данные, которые поступили во время обработки). Использование
#+ соответствующих lock-файлоа позволяет вести обработку на нескольких машинах
#+ одновременно, не производя дублирующих вычислений [которые, в моем случае,
#+ выполняются в течении нескольких часов, так что для меня это очень важно].
#+ Кроме того, поскольку поиск необработанных файлов всегда начинается с
#+ самого начала, можно задавать приоритеты в именах файлов. Конечно, можно
#+ обойтись и без `continue 2', но тогда придется ввести дополнительную
#+ проверку -- действительно ли был обработан тот или иной файл
#+ (чтобы перейти к поиску следующего необработанного файла).
Конструкция continue Nдовольно сложна в понимании и применении, поэтому, вероятно лучше будет постараться избегать ее использования.
Инструкции caseи selectтехнически не являются циклами, поскольку не предусматривают многократное исполнение блока кода. Однако, они, как и циклы, управляют ходом исполнения программы, в зависимости от начальных или конечных условий.
case (in) / esac
Конструкция caseэквивалентна конструкции switchв языке C/C++. Она позволяет выполнять тот или иной участок кода, в зависимости от результатов проверки условий. Она является, своего рода, краткой формой записи большого количества операторов if/then/else и может быть неплохим инструментом при создании разного рода меню.
case"$ variable " in "$ condition1 " ) command ... ;; "$ condition2 " ) command ... ;; esac
Заключать переменные в кавычки необязательно, поскольку здесь не производится разбиения на отдельные слова.
Каждая строка с условием должна завершаться правой (закрывающей) круглой скобкой ).
Каждый блок команд, отрабатывающих по заданному условию, должен завершаться двумя символами точка-с-запятой ;;.
Блок caseдолжен завершаться ключевым словом esac( case записанное в обратном порядке).
Пример 10-24. Использование case
#!/bin/bash
echo; echo "Нажмите клавишу и затем клавишу Return."
read Keypress
case "$Keypress" in
[a-z] ) echo "буква в нижнем регистре";;
[A-Z] ) echo "Буква в верхнем регистре";;
Читать дальше