19.7.6. Управляющие структуры и циклы
19.7.6. Управляющие структуры и циклы
К управляющим структурам относятся:
• Конструкция if-fi.
• Конструкция case-esac.
Конструкция if-fi
Общий синтаксис конструкции if-fi:
if список1 then
список2
elif
список3
then
список4
else
список3
fi
Конструкция if-fi работает так же, как и в других языках программирования. Если список1 (условие) истинный, выполняется список1, иначе выполняется список3 и проверяется его истинность и т.д. Допускается неограниченная вложенность операторов if. Например:
if uuencode myfile myfile > myfile.uu; then
echo "Успешное конвертирование";
else
echo "Ошибка";
fi
Можно использовать сокращенный вариант:
if список1 then
список2
fi
Например:
if [ $? –ne 0 ]; then echo "Ошибка. См. файл протокола"; fi;
Вместо списка команд удобно использовать команду test или выражение [условие]. Например, следующие выражения аналогичны:
test –e /etc/passwd
[-е /etc/passwd]
И первое, и второе выражение проверяют существование файла /etc/passwd. Другие опции команды test представлены в табл. 19.38.
Опции команды test Таблица 19.38
Опция Возвращаемое значение и описание -d файл Истина, если файл существует и является каталогом -е файл Истина, если файл существует -f файл Истина, если файл существует и является простым файлом -k файл Истина, если файл существует и для него установлен бит односторонней операции -L файл Истина, если файл существует и является ссылкой -r файл Истина, если файл существует и доступен для чтения -s файл Истина, если файл существует и его размер больше 0 -х файл Истина, если файл существует и является исполнимым -w файл Истина, если файл существует и доступен для записи -о файл Истина, если файл существует и принадлежит данному пользователю -z строка Истина, если длина строки равна 0 -n строка Истина, если длина строки не равна 0Команда test, в случае успешного завершения, возвращает значение истина, то есть 0 — успешное завершение. Если в скобках стоит непустое слово, test возвратит тоже 0, например:
[ word ]; echo $?
0
[]; echo $?
1
В первом случае возвращается истина (true), на экран выводится ноль — код удачного (безошибочного) завершения программы. Во втором случае на экран выводится единица — команда test возвратила значение ложь (false). Сравнение строк осуществляется следующим образом: выражения str1 = str2 или str1 == str2 истинны, когда строки str1 и str2 равны. Обратите внимание: между двумя символами равно не должно быть пропуска!
Символ ! инвертирует любое условие команды test, например, выражение str1 != str2 будет истинным, когда строки str1 и str2 не равны между собой. Символ ! является символом логической операции NOT (отрицание). Кроме этого символа, можно использовать опции команды –о и –а, которые обозначают логические операции ИЛИ (OR) и И (AND). Например:
str="word"; export str; ["$str" –a –f /etc/passwd]; echo $?
0
str=""; export str; ["$str" –a –f /etc/passwd]; echo $?
1
В первом случае непустая строка str возвращает истину, опция —f возвращает также истину, потому что файл /etc/passwd существует всегда. Результат операции И: истина И истина = истина, поэтому на экране вы увидите 0.
Во втором случае пустая строка str возвратит ложь, а опция –f возвращает истину. Результат операции И: ложь И истина = ложь. Если вы забыли законы логики, освежите свои знания с помощью табл. 19.39.
Логические операции Таблица 19.39
AND True False OR True False XOR True False True True False True True True True False True False False False False True False False True FalseОперация XOR — это исключающее ИЛИ. Данная операция не используется при создании сценариев с помощью интерпретатора bash.
Для сравнения целых чисел используются опции команды test,приведенные в табл. 19.40.
Сравнение целых чисел Таблица 19.40
Опция Описание -eq Равно -ne Не равно -It Меньше -gt Больше -le Меньше или равно -ge Больше или равноИнтерпретатор bash воспринимает строки, как целые числа. Если нужно обнулить строку, то это достигается таким присваиванием: х=0.
Пример.
х=124 ; export х ; [ 111 –It "$х" ] ; echo $?
0
Поскольку 111 меньше, чем 124, на экране вы увидите 0 (истина).
Примечание. Во всех примерах, вы, наверное, заметили использование команды export. Это необходимо для того, чтобы порожденному процессу (не забывайте: test — это отдельная программа) переменнаях была доступна.
Теперь, когда мы уже знакомы с конструкциями test и if, рассмотрим небольшой пример, демонстрирующий вложенность операторов if и использование команды test. Пример приведен в листинге 19.2.
Листинг 19.2. Пример вложенности операторов
echo –n "Какую оценку ты получил сегодня по программированию? "
read x
if [ $х = 5 ]
then echo "Отлично !"
elif [ $х = 4 ]
then echo "Хорошо"
elif [ $x = 3 ]
then echo "Удовлетворительно"
elif [ $x = 2 ]
then echo "Надо бы пересдать"
else
echo "Как вообще можно было получить такую оценку???"
fi
Если вы введете 5, сценарий отобразит на экране слово «Отлично», при вводе 4 вы увидите слово «Хорошо» и так далее. Если вы введете 0, 1 или число больше пяти, вы увидите на экране последнюю фразу: «Как вообще можно было получить такую оценку???».
Конструкция case-esac
Конструкция выбора (case — выбор) имеет следующий синтаксис:
case значение in
шаблон1) список1 ;;
…
шаблонN) списокN ;;
esac
Рассмотрим сценарий (см. листинг 19.3), аналогичный сценарию 19.2, но использующий конструкцию case вместо if.
Листинг 19.3. Пример использования оператора case
echo –n " Какую оценку ты получил сегодня по программированию? "
read x
case $x in
5) echo "Отлично !" ;;
4) echo "Хорошо" ;;
3) echo "Удовлетворительно" ;;
2) echo "Надо бы пересдать" ;;
*) echo "Как вообще можно было получить такую оценку???" ;;
esac
Работа сценария аналогична первому сценарию: при вводе оценок 2, 3, 4, 5 будут отображены соответствующие сообщения, а во всех остальных случаях — последнее сообщение.
Примечание. Структура оператора case больше напоминает структуру оператора case в языке Pascal, чем в языке С. Последняя строка выбора с шаблоном *) будет выбрана, когда не произойдет ни одного совпадения с ранее указанными шаблонами. Если же произошло совпадение с шаблоном шаблонN, то будет выполнен список списокN. После выполнения списка команд списокN будет произведен выход из структуры case —так же как и в Pascal. В языке С наблюдается нечто другое: если будет обнаружено совпадение, скажем с шаблоном3, то будут выполнены последовательности операторов 3, 4, 5, … N. Чтобы прервать выполнение блока case в языке С нужно использовать оператор break. В bash же такого нет.
Если для одного списка команд нужно описать два или более шаблонов, используется символ | (OR).
case num in
1|2|3) echo "1 or 2 or 3" ;;
4|5) echo "4 or 5" ;;
*) echo "other num" ;;
esac
Циклы
Интерпретаторы bash и ksh поддерживают циклы for, while, until, select, a интерпретатор sh только for и while.
Синтаксис цикла for:
for имя_переменной in список1 do
список2
done
Простой пример:
for i in 1 2 3 4 5; do echo $i; done
На экране вы увидите:
1 2 3 4 5
Еще раз напомню, что любой список в bash должен заканчиваться точкой с запятой. Начинающие «программисты» делают много ошибок, связанных именно с этой особенностью списков. Пример использования: построчно вывести содержимое файла /etc/passwd вы можете с помощью такого цикла:
for str in `cat /etc/passwd` do
echo "$str";
done
Цикл for закончит свою работу, когда будет обработан последний элемент списка, в данном случае, когда на экран будет выведена последняя строка файла /etc/passwd.
Синтаксис цикла while:
while список1 do
список2
done
Цикл while будет выполняться, пока условие, заданное в списке список!,
будет истинным. Поэтому цикл while иногда называют циклом с истинным условием. Например,
х=1
while [$х –It 10]
do
echo $х
X = $(( $Х + 1 ))
done
На экране вы увидите:
1 2 3 4 5 6 7 8 9
Когда переменная х примет значение 10, цикл завершит свою работу, так как программа test вернет значение false (x уже не меньше, а равен 10). Цикл until (до) имеет похожую структуру, но выполняется несколько иначе:
until список1 do
список2
done
Цикл until прекратит работу, когда условие, указанное в списке список1, станет истинным. Другими словами, он будет выполняться пока это условие ложно. Цикл while, наоборот, выполняется пока условие истинно. Лучше всего разница между этими циклами видна на примере (сравните листинги 19.4 и 19.5)
Листинг 19.4. Цикл while
х=1;
while ! [$х –ge 10]
do echo $x echo $x
X = $ (($Х + 1))
done
Листинг 19.5. Цикл until
х=1;
until [$x –ge 10]
do
X=$(($Х + 1))
done
Циклы, приведенные в листингах 19.4 и 19.5, выведут одинаковую последовательность цифр на экран:
1 2 3 4 5 6 7 8 9 10
Рассмотрим еще один полезный цикл select, который позволяет создавать нумерованные пункты меню. Его конструкция такова:
select имя in список1
do
список2
done
Пример:
echo "Выберите файл для просмотра
select file in /home/den/temp/* QUIT
do
if [-e $file]; then less $file
else
break
done;
В моем временном каталоге /home/den/temp находится всего два файла — file.txt, proto.txt, поэтому на экране монитора будет отображено следующее:
Выберите файл для просмотра:
/home/den/temp/.
/home/den/temp/..
/home/den/temp/file.txt
/home/den/temp/proto.txt
QUIT
Первые два файла — это ссылки на текущий и родительский каталоги. Пункты меню 3 и 4 — это файлы, которые можно выбрать для просмотра. QUIT — это последний элемент списка. При его выборе сработает оператор break и цикл завершится.
Данный текст является ознакомительным фрагментом.