Читать интересную книгу Искусство программирования на языке сценариев командной оболочки - Мендель Купер

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 23 24 25 26 27 28 29 30 31 ... 96

fi

done

echo

done

echo

exit 0

Команда continue, как и команда break, может иметь необязательный параметр. В простейшем случае, команда continue передает управление в начало текущего цикла, а команда continue N прерывает исполнение текущего цикла и передает управление в начало внешнего цикла, отстоящего от текущего на N уровней (причем 1-й уровень -- это уровень текущего цикла, прим. перев.).

Пример 10-22. Передача управление в начало внешнего цикла

#!/bin/bash

# Команда "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 довольно сложна в понимании и применении, поэтому, вероятно лучше будет постараться избегать ее использования.

10.4. Операторы выбора

Инструкции 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 "Буква в верхнем регистре";;

[0-9] ) echo "Цифра";;

* ) echo "Знак пунктуации, пробел или что-то другое";;

esac # Допускается указыватль диапазоны символов в [квадратных скобках].

# Упражнение:

# --------

# Сейчас сценарий считывает нажатую клавишу и завершается.

# Измените его так, чтобы сценарий продолжал отвечать на нажатия клавиш,

# но завершался бы только после ввода символа "X".

# Подсказка: заключите все в цикл "while".

exit 0

Пример 10-25. Создание меню с помощью case

#!/bin/bash

# Грубый пример базы данных

clear # Очистка экрана

echo " Список"

echo " ------"

echo "Выберите интересующую Вас персону:"

echo

echo "[E]vans, Roland"

echo "[J]ones, Mildred"

echo "[S]mith, Julie"

echo "[Z]ane, Morris"

echo

read person

case "$person" in

# Обратите внимание: переменная взята в кавычки.

"E" | "e" )

# Пользователь может ввести как заглавную, так и строчную букву.

echo

echo "Roland Evans"

echo "4321 Floppy Dr."

echo "Hardscrabble, CO 80753"

echo "(303) 734-9874"

echo "(303) 734-9892 fax"

echo "[email protected]"

echo "Старый друг и партнер по бизнесу"

;;

# Обратите внимание: блок кода, анализирующий конкретный выбор, завершается

# двумя символами "точка-с-запятой".

"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 "[email protected]"

echo "Подружка"

echo "День рождения: 11 февраля"

;;

# Информация о Smith и Zane будет добавлена позднее.

* )

# Выбор по-умолчанию.

# "Пустой" ввод тоже обрабатывается здесь.

echo

echo "Нет данных."

;;

esac

echo

# Упражнение:

# --------

# Измените этот сценарий таким образом, чтобы он не завершал работу

#+ после вывода информации о персоне, а переходил на ожидание нового

#+ ввода от пользователя.

exit 0

Очень хороший пример использования case для анализа аргументов, переданных из командной строки.

#! /bin/bash

case "$1" in

"") echo "Порядок использования: ${0##*/} <filename>"; exit 65;; # Параметры командной строки отсутствуют,

# или первый параметр -- "пустой".

# Обратите внимание на ${0##*/} это подстановка параметра ${var##pattern}. В результате получается $0.

1 ... 23 24 25 26 27 28 29 30 31 ... 96
На этом сайте Вы можете читать книги онлайн бесплатно русская версия Искусство программирования на языке сценариев командной оболочки - Мендель Купер.
Книги, аналогичгные Искусство программирования на языке сценариев командной оболочки - Мендель Купер

Оставить комментарий