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

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

На нашем сайте KnigaRead.com Вы можете абсолютно бесплатно читать книгу онлайн Мендель Купер, "Искусство программирования на языке сценариев командной оболочки" бесплатно, без регистрации.
Перейти на страницу:

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.

Перейти на страницу:
Прокомментировать
Подтвердите что вы не робот:*