- •15 Спо часть 1 Лек 1_4 (Кузнецова а.В.)
- •Командные интерпретаторы. Программирование на языке shell
- •Группировка команд.
- •Перенаправление команд
- •Генерация имен файлов
- •Специальные переменные
- •Условный оператор if
- •Оператор вызова (case)
- •Оператор цикла с перечислением (for)
- •Оператор цикла с истинным условием (while)
- •Оператор цикла с ложным условием (until)
Оператор цикла с ложным условием (until)
Оператор цикла until имеет структуру:
until условие
do
список команд
done
где until - служебное слово определяющее тип цикла с ложным условием. Список команд в теле цикла (между do и done) повторяется до тех пор, пока сохраняется ложность условия или цикл не будет прерван изнутри специальными командами (break, continue или exit). При первом входе в цикл условие не должно выполняться.
Отличие от оператора while состоит в том, что условие цикла проверяется на ложность (на ненулевой код завершения последней команды тела цикла) проверяется ПОСЛЕ каждого (в том числе и первого!) выполнения команд тела цикла.
Программистов, знакомых с операторами until в других языках может вначале сбивать такая семантика этого оператора.
Примеры.
until false
do
read x
if [ $x = 5 ]
then echo enough ; break
else echo some more
fi
done
здесь программа с бесконечным циклом ждет ввода слов (повторяя на экране фразу "some more"), пока не будет введено "5". После этого выдается "enough" и команда "break" прекращает выполнение цикла.
Пример ("Ожидание полдня") иллюстрирует возможность использовать в условии вычисления.
until date | grep 12:00:
do
sleep 30
done
Здесь каждые 30 секунд выполняется командная строка условия. Команда date выдает текущую дату и время. Команда grep получает эту информацию через конвейер и пытается совместить заданный шаблон 12:00: с временем, выдаваемым командой date. При несовпадении grep выдает код возврата 1, что соответствует значению ложь, и цикл "выполняет ожидание" в течение 30 секунд, после чего повторяется выполнение условия. В полдень (возможно с несколькими секундами) произойдет сравнение, условие станет истинным, grep выдаст на экран соответствующую строку и работа цикла закончится.
Пустой оператор
Пустой оператор имеет формат
:
Ничего не делает. Возвращает значение 0. Например, в конструкции while : или ставить в начале командного файла, чтобы гарантировать, что файл не будет принят за выполняемый файл для "csh".
Функции в shell
Функция позволяет подготовить список команд shell для последующего выполнения.
Описание функции имеет вид:
имя()
{
список команд
}
после чего обращение к функции происходит по имени. При выполнении функции не создается нового процесса. Она выполняется в среде соответствующего процесса. Аргументы функции становятся ее позиционными параметрами; имя функции - ее нулевой параметр. Прервать выполнение функции можно оператором return [n], где (необязательное) n"- код возврата.
Примеры скриптов
Использование PID для генерации имени файла
test4
echo Now Prosess ID: $$ echo File name: $0 tempfile=tmp.$$ echo $tempfile |
Now Prosess ID: 4795 File name: ./test4.bat tmp.4795 |
самостоятельно |
теперь в цикле – сгенерировать много файлов tmp.4795.1 tmp.4795.2 . . . . |
test44
############################################ #Generacia unicalnyx imen failov na baze PID ############################################ #!/bin/bash echo File name: $0 #Imya programmy echo Now Prosess ID: $$ #$$ = PID declare -a mass #ob'yavlenie massiva N=10 #razmer massiva ########################## #formirovanie mass v cycle ########################## i=0 while [ "$i" -lt "$N" ] do mass[$i]=$$.$i i=`expr $i + 1` done echo ${mass[@]} #vyvod vsego massiva srazu ########################## #vyvod massiva v cyccle ########################## i=0 while [ "$i" -lt "$N" ] #vyvod po elementam do echo ${mass[$i]} let "i = $i + 1" done ########################## #vvod massiva s klaviatury ########################## declare -a mas #massiv strok echo Enter elem, separated by space read mas count=${#mas[@]}; echo vsego $count elements i=0 while [ $i -lt $count ] do echo ${mas[$i]} let i++ done exit 0 |
Результаты работы: File name: ./test44.bat Now Prosess ID: 4744 4744.0 4744.1 4744.2 4744.3 4744.4 4744.5 4744.6 4744.7 4744.8 4744.9 4744.0 4744.1 4744.2 4744.3 4744.4 4744.5 4744.6 4744.7 4744.8 4744.9 Enter elem, separated by space ss ff ffg vsego 1 elements ss ff ffg |
scr5
#ARIFMETIC OPERATION #!/bin/bash echo File name: $0 #Imya programmy a=10 echo $a let a=a+2 #ili let "a = $a + 20" ili let a="a+2" lubye " ' echo $a #STYLE C b=$(($a+10)); echo -n $b ;((b++)); echo " $b" ((c=5)); echo -n $c; ((c--)); echo " $c" #INTEGER and STRING aa=4 bb=5 ; echo "aa=$aa bb=$bb" if [ $aa -ne $bb ] # -eq -ne -gt -ge -lt -le then echo "ARIFMETIC: $aa not equal $bb" fi if [ $aa != $bb ] # = ili == != \< \> -z -n then echo "STRING: $aa not equal $bb" fi if [ $aa -lt $bb -a $aa -lt $bb ] # then echo "ARIFMETIC and LOGIC : $aa < $bb and $aa <= $bb" # fi exit 0 |
Результаты работы: File name: ./scr5 10 12 22 23 5 4 aa=4 bb=5 ARIFMETIC: 4 not equal 5 STRING: 4 not equal 5 ARIFMETIC and LOGIC : 4 < 5 and 4 <= 5
|
Сдвиг параметров test1 #!/bin/bash echo my script1 $0 echo $1 $2 $3 shift echo $1 $2 $3 Проверка аргументов и выдача сообщения, как д.б. запущена программа test2 #!/bin/bash if [ $# -lt 2 ] then echo usage: $0 arg1 arg2 exit 1 fi Встречается ли имя alla в файле паролей, т.е. есть ли такой пользователь?
test3
grep alla -q /etc/passwd
if [ $? -ne 0 ]
then
echo polzovatel alla not register
else
echo polzovatel alla is register
fi
То же, но имя пользователя определяется первым параметром
test33
grep $1 -q /etc/passwd
if [ $? -ne 0 ]
then
echo polzovatel $1 not register
else
echo polzovatel $1 is register
fi