Лекция: Условные выражения
Синтаксис условного оператора:
if условие
then
command 1
command 2
.. .
fi
Команды command1 и command2 будут выполнены, если условие истинно. Условие может генерироваться одной или несколькими командами. По существу, ложность или истинность условия определяется кодом возврата последней выполненной команды. Например:
if grep alla /etc/passwd >dev/null 2>&1 #если слово alla в файле паролей найдено
then
echo alla present into password file #то вывести сообщение
fi
Наиболее распространенным способом генерации условия для оператора if является команда test, которая вычисляет логическое выражение и возвращает 0, если выражение истинно, и 1 в противном случае. Синтаксис команды:
test выражение или [выражение]
Выражения, используемые в команде test
Выражения с файлами | |
-r файл | истина, если файл существует и доступен для чтения. |
-w файл | истина, если файл существует и доступен для записи. |
-x файл | истина, если файл существует и является выполняемым |
-f файл | истина, если файл существует и является обычным файлом |
-d файл | истина, если файл существует и является каталогом. |
-c файл | истина, если файл существует и является специальным символьным файлом. |
-b файл | истина, если файл существует и является специальным блочным файлом |
-p файл | истина, если файл существует и является именованным каналом. |
-u файл | истина, если файл существует и его режим содержит бит переустановки идентификатора пользователя. |
-g файл | истина, если файл существует и его режим содержит бит переустановки идентификатора группы. |
-k файл | истина, если файл существует и его режим содержит бит навязчивости |
-s файл | истина, если файл существует и имеет ненулевой размер |
-t [дескриптор файла] | истина, если открытый файл с указанным дескриптором (по умолчанию 1) существует и ассоциирован с терминалом. |
Выражения со строками | |
-z s1 | истина, если длина строки s1 нулевая. |
-n s1 | истина, если длина строки s1 ненулевая. |
s1 = s2 | истина, если строки s1 и s2 равны. |
s1 != s2 | истина, если строки s1 и s2 не равны. |
s1 | истина, если s1 — непустая строки. |
Сравнение целых чисел | |
n1 -eq n2 | истина, если целые числа n1 и n2 алгебраически равны. на месте -eq могут быть также операции сравнения -ne (не равно), -gt (больше), -ge (больше или равно), -lt (меньше), -le (меньше или равно). |
Логические операторы (для объединения нескольких условий; приведены в порядке уменьшения приоритета): | |
! | унарная операция отрицания |
-a | логическое И. |
-o | логическое ИЛИ. |
Примеры:
if [ -x /etc/ineted ] #если исполняемый файл сущ. then /etc/ineted #файл запускается на выполнение echo «запущен сервер ineted» fi | #если ответ пользователя «N» или «n» if ["$ANSW" = «N» –o "$ANSW" = «n»] then exit fi |
Циклы
Команды в теле оператора while будут выполняться, пока условие не станет ложным:
while условие
do
command1
command2
.. .
done
Команды в теле оператора until будут выполняться, пока условие не станет истинным:
until условие
do
command1
command2
.. .
done
Как и в случае с оператором if, условие генерируется кодом возврата команды, например test.
Оператор for обеспечивает выполнение цикла столько раз, сколько слов имеется в списке. При этом переменная var последовательно принимает значения, равные словам из списка. Список может формироваться различными способами, например как вывод некоторой команды (‘имя_команды’) или помощью шаблонов shell. В другой форме for, когда список отсутствует, переменная var принимает значения позиционных параметров, переданных скрипту:
for var in спиок for read var
do do
command1 command1
command2 command2
..... .
done done
Примеры:
#построчно считывает записи из файла myfile #и присваивает их переменным v1 — v5: cat /home/alla/myfile | while read v1 v2 v3 v4 v5 do # здесь любые действия с файлами done | #переменной n вначале присваивается значение 0, #а не пустая строка, т.к. команда expr работает #с shell-переменными как с целыми числами, #а не как со строками. n=0 while [ $n -lt 50 ] # пока n < 50 do n=`expr $n + 1` cat file-22 > /dev/lp done |
# Выдает имена всех подкаталогов каталога # с именем $dir for i in $dir/* do if [ -d $i ] then echo $i fi done #в каталогах /tmp, /usr/tmp и /home/tmp #отыскиваются и удаляются все файлы, #последний доступ к которым #осуществлялся более недели назад for dir in /tmp /usr/tmp /home/tmp do find $dir! –type в –atime +7 –exec rm {} \; done | Пусть proc-sort – это функция, которая последовательно сортирует указанные файлы, результаты сортировки выводит в другую консоль (/dev/tty2) и направляет в файлы f1_sorted f2_sorted и f3_sorted... cat $1 | sort | tee /dev/lp > ${1}_sorted... Головная программа будет следующей:... for i do proc-sort $i done... Отсутствие после i служебного слова in с перечислением имен говорит о том, что список поступает через параметры команды. Результат примера можно получить, набрав myscript f1 f2 f3 |
#программа с бесконечным циклом ждет #ввода слов (повторяя на экране фразу #some more), пока не будет введено «5». # после этого выдается enough и команда #«break» прекращает выполнение цикла. until false do read x if [ $x = 5 ] then echo enough; break else echo some more fi done | #«Ожидание полдня» — иллюстрирует возможность #использовать в условии вычисления. until date | grep 12:00: do sleep 30 done Здесь каждые 30 секунд выполняется командная строка условия. Команда date выдает текущую дату и время. Команда grep получает эту информацию через конвейер и пытается совместить заданный шаблон «12:00:» с временем, выдаваемым командой date. При несовпадении grep выдает код возврата 1, что соответствует значению ложь, и цикл «выполняет ожидание» в течение 30 секунд, после чего повторяется выполнение условия. В полдень (возможно с несколькими секундами) условие станет истинным, работа цикла закончится. |