| |
Занятие 8.
Тема: Командные оболочки. Занятие второе.
Вид занятия: лекция, практическое занятие.
Учебные вопросы:
1. Программирование для Bash.
Время: 90 минут
Литература:
1. Системная справочная служба Linux Man
2. Тейнсли Д. “Linux и UNIX: программирование в shell. Руководство
разработчика”. Перевод с английского - К.: Издательская группа
BHV, 2001. - 464 с.
Ход занятия.
Сценарии командных оболочек играют в Linux огромную роль. Кроме того, что каждый пользователь стремится по максимуму автоматизировать выполняемую им работу с помощью сценариев shell, так и сценарии инициализации системы и множества приложений есть ничто иное как просто сценарии shell. Как и на позапрошлом занятии, мы с Вами будем рассматривать программирование в shell на базе Bourne Shell.
1. Любой сценарий для bash начинается с указания в первой строке редактируемого файла комбинации:
#!/bin/bash
Эта последовательность указывает на программу, которую следут использовать для обработки данного сценария - в нашем случае командную оболочку bash.
Язык bash довольно мощный. Важную часть представляют собой объявления переменных. Принять называть переменные буквами верхнего регистра, например:
#!/bin/bash
TERM=vt100
CONTER=0
Для извлечения значения переменной используются следующий синтаксис:
ALFA=$BETA+$GAMMA
Значок $ означает, что нужно извлечь значение переменной BETA, а не использовать строку “BETA”. Переменной можно присвоить вывод какой-либо команды. При этом переменная станет массивом, разделителем записей в котом будут служить символы пробела, табуляции и перевода строки. Для этого выполняемую команду необходимо заключить в обратные апострофы и присвоить переменной:
FILES=`/bin/ls -a /home/student`
Вывод на экран значений переменных, или просто фраз производится с помощью оператора echo:
echo $ALFA summ BETA and GAMMA
echo Done.
При выводе выводимую информацию можно заключать в одинарные(') и двойные(“)кавычки. Одинарные полностью выводят текст, написанный внутри них, а в двойных указанные переменные заменяются их значениями:
[gserg@WebMedia serial]$ echo '$USER'
$USER
[gserg@WebMedia serial]$ echo “$USER”
student
[gserg@WebMedia serial]$
В качестве комментариев применяется знак #. Он может быть использован как в начале, так и в середине строки:
#Временный каталог
TMP='/tmp' #используем кавычки
Как часть сценария может быть использована любая доступная команда операционной системы:
#очистим экран
clear
Bash поддерживает несколько операций сравнения. В случае, если условие верно, то оператор сравнения возвращает 0 (true). Проверить возвращаемое значение можно с помощью специального значения $?. Перечислю их:
#проверка кода возврата последней команды
[ -d abcd ]
echo $?
#проверка прав доступа к файлу:
[ -d abcd ] #является ли файл abcd каталогом?
[ -f abcd ] #является ли файл abcd обычным файлом?
[ -L abcd ] #является ли файл abcd символической ссылкой?
[ -r abcd ] #есть ли доступ на чтение к файлу abcd?
[ -w abcd ] #есть ли доступ на запись к файлу abcd?
[ -s abcd ] #файл abcd имеет ненулевой размер (он не пуст)?
[ -u abcd ] #имеет ли файл abcd установленный бит SUID?
[ -x abcd ] #является ли файл abcd исполняемым?
#проверка строк
[ -z $STRING ] #пуста ли строка STRING?
[ -n $STRING ] #строка STRING не пуста?
[ $STRING = $STRING1 ] #равны ли строки STRING и STRING1?
[ $STRING != $STRING1 ] #строки STRING и STRING1 не равны?
#проверка чисел
#при проверке чисел в условии их обязательно необходимо
#заключить в двойные кавычки
[ $DIGIT -eq $DIGIT1 ] #равны ли числа DIGIT и DIGIT1?
[ $DIGIT -ne $DIGIT1 ] #числа DIGIT и DIGIT1 не равны?
[ $DIGIT -gt $DIGIT1 ] #число DIGIT больше DIGIT1?
[ $DIGIT -lt $DIGIT1 ] #число DIGIT меньше DIGIT1?
[ $DIGIT -gе $DIGIT1 ] #число DIGIT больше или равно DIGIT1?
[ $DIGIT -lе $DIGIT1 ] #число DIGIT меньше или равно DIGIT1?
Сценарию на bash могут быть переданы параметры командной строки. Значения их можно получить с помощью переменных $0, $1, $2 .. $n-1, $n. При этом $0 - имя файла сценария, $1 - первый параметр, $2 - второй, ... $n - последний.
Но операторы сравнения без операторов ветвления бесполезны. Простейшим оператором ветвления в языке сценариев bash является оператор if-then-else-fi. Полная структура для оператора выглядит следующим образом:
if <оператор сравнения1>; then
<действия 1>
elif <оператор сравнения2>; then
<действия 2>
else
<действие 3>
fi
Оператор if позволяет упрощать конструкцию. Разделы elif и else не являются обязательными. Для правильной работы достаточно использования только конструкции if-fi.
Для примера приведу скрипт:
#!/bin/bash
if [ -f /etc/passwd ]; then
echo “/etc/passwd - обычный файл”
else
echo “/etc/passwd - не обычный файл”
fi
exit
В этом сценарии проверяется, обычный ли файл /etc/passwd и выводится соответствующее сообщение на экран.
Естественно мы не сможем обойтись и без таких конструкций, как циклы.
Простейшим циклом является цикл перебора for.
for <ЭЛЕМЕНТ> in $<СПИСОК>
do
<действия>
done
Циклу передается переменная со списком параметров, разделенных пробелом, знаком перевода строки или табуляции. Дальше цикл выполняет действия для каждого элемента из списка, например:
#!/bin/bash
echo “Поиск каталогов в $HOME”
echo
#перейдем в домашний каталог
pushd $HOME
#получим список файлов
LIST = `ls -a $HOME`
#организуем цикл для каждого из
#значений в переменной LIST
for ITEM in $LIST
do
#если вхождение - каталог, выведем его на экран
if [ -d $ITEM ]; then
echo “$ITEM”
fi
done
#вернемся в прежнюю директорию
popd
#выход
exit
Однако цикл перебора подходит нам не во всех случаях. Во многих случаях нам необходим цикл с условием. Это цикл while.
while <условие>
do
<действия>
done
Цикл while выполняется до тех пор, пока истинно <условие>. Попробую показать на примере организации цикла со счетчиком. Для вычислений я буду использовать команду expr, позволяющую выполнять математические операции с переменными bash:
#!/bin/bash
#определяем наличие первого параметра
#командной строки
if [ -z $1 ]; then
echo “Использование: $0 количество_проверок”
exit
fi
#очистим экран
clear
#определим переменную счетчика цикла
COUNTER=0
#организуем цикл на $1 итераций
while [ $COUNTER -lt $1 ]
do
echo “Загрузка системы (за $1 секунд)”
echo echo “секунда $COUNTER”
echo “-- загрузка системы --”
#команда определения средней загрузки
/usr/bin/uptime
echo “-- место на дисках --”
#определение свободного места на винчестере
df -h
echo “----------------”
echo
#пауза 1 секунду
/bin/sleep 1
#очистим экран
clear
#приращение переменной цикла
COUNTER=`expr $COUNTER + 1`
done
#выход
exit
Организация вывода имени программы не очень удачно выполнено в данном случае, потому что будет выводится не только имя запущенной программы, а и путь, набранный нами в командной строке. Исправить это нам поможет директива basename, выделяющая из пути имя файла. Вот как будет выглядеть фрагмент приведенного выше сценария с ее применением:
#!/bin/bash
#определяем наличие первого параметра
#командной строки
if [ -z $1 ]; then
echo Использование: `basename $0` количество_проверок
exit
fi
...
Закладки на сайте Проследить за страницей |
Created 1996-2024 by Maxim Chirkov Добавить, Поддержать, Вебмастеру |