Лабораторная работа 5
Любая из стандартных оболочек операционных систем семейства UNIX/Linux позволяет создавать командные файлы (еще называемые, сценариями, от англ. script). Следует иметь в виду, что они выполняются так, как будто команды, записанные в нем, последовательно вводятся с клавиатуры. Этот режим называется интерпретация. При котором трудно ожидать эффективной работы. Но программы, написанные на таком языке, учитывая разнообразие поддерживаемых ими средств, могут быть довольно сложными.
Сценарии используют для автоматического выполнения некоторого набора команд. Это удобно, если такие команды выполняется постоянно. Такая ситуация может быть связана с разными системными событиями, например:
– загрузка операционной системы;
– регистрация в системе очередного пользователя;
– запуск программного комплекса, обеспечивающего системные функции (иногда говорят «службы»).
Для понимания системных сценариев надо знать правила их записи. Поэтому первым этапом знакомства со сценариями будет изучение их синтаксиса. В файле сценария могут быть комментарии. Они начинается символом «#» и заканчивается в конце строки. Сценарий представляет собой текстовый файл. В первой его строке обычно записывается имя интерпретатора (например, #!/bin/bash) или пустой оператор:.
|
|
Как уже отмечалось, если мы хотим запустить на выполнение сценарий, он должен обладать правом на выполнение (параметр х), которое для владельца файла добавляются командой
chmod u+x <имя файла>
Но запустить текстовый файл с командами не имеющий прав на выполнение можно использую символ «.» (точка)-см. лабораторная работа 2, пункт 2.3.
Командные оболочки (командные интерпретаторы) семейства UNIX/Linux имеют развитый язык программирования в большой степени ориентированный на автоматизацию задач администрирования ОС. В файле сценария кроме команд (имени исполнимого файла с параметрами) могут содержаться операторы. В последних, естественно, используют переменные.
В рамках этой лабораторной работы будет затронуты не все возможности языковых средств сценариев оболочек UNIX/Linux (не будут затронуты вопросы создание функции и использование массивов).
Начнем описание языка сценария оболочки UNIX с переменных. Можно выделить несколько их типов. Один из них был рассмотрен ранее. Это переменные окружения. Примерами их являются HOME и TERM.
Второй тип переменных создается разработчиком сценария. Их часто называют пользовательские (или переменные, определяемые пользователем). Задать их значения можно непосредственным присваиванием или командой read. Помимо такого типа переменных, а также рассмотренных ранее переменных окружения, язык программирования сценариев имеет собственные, встроенные переменные и предопределенные или специальные преременные.
|
|
Приведем два способа присваивания значений пользовательским переменным:
1. Непосредственное присваивание для переменных символьного типа.
переменное=значение
2. Непосредственное присваивание для переменных числовых значений.
let переменное=значение
Такие операторы являются одновременно и объявлением переменных. В данном случае значением может быть и выражения. Если значение переменной надо использовать в выражении, то перед ее именем ставиться символ «$». Далее будет приведено несколько примеров присваивания значений переменным, в которых для вывода значений используем оператор echo.
Перейдем к описанию встроенных переменных. Их имя, как правило, состоит из двух символов. Первым из них является «$». К примеру, в такой переменной $0 содержится имя файла сценария. Если в сценарии с именем scr1 записаны строки, среди которых есть такая
echo “Выполняется“ $0
то результат ее выполнения будет таким
Выполняется scr1
Такие специальные переменные $1, $2,... содержат параметры вызова сценария. Если таких параметров больше 9, то используем <Shift>. Приведем пример. Если сценарий с именем scr1 вызывался такой строкой
Scr1 1 two
то такие операторы
echo $1 $2
приведут к следующему результату
1 two
а после такого
Shift
echo $1
будет выведено только
two
Другими встроенными переменными сценариев являются такие:
$# - число параметров сценария.
$? - код возврата последнего процесса.
$* и $@ - значения всех параметров переданных сценарию.
Приведем пример использования встроенных переменных оболочки. В нем и далее последние две строки играют такую роль. Первая, после вывода результатов работы скрипта, выводит сообщение press key. Система останавливается и продолжит работу только после нажатия клавиши <Enter>.
Текст сценария scr2 | РЕЗУЛЬТАТ и пояснения |
#!/bin/bash clear echo echo kol_vo param $# echo echo "all param => $*" echo "all param 2 => $@" echo "param_ry: one $1 | two $2 | three $3" echo press key read q | Если сценарий вызвать следующим образом, scr2 1 two 3-th то получим следующие результаты. 1 two 3-th 1 two 3-th 1 | two | 3-th press key |
Теперь перейдем к описанию операторов, используемых в сценариях. Выше мы уже упоминали оператор echo, а также то, что для вывода на экран значений переменных используется «$». Для ввода значений переменной а используется оператор read. В приведенном примере показано присвоение символьных и численных значений переменным.
Текст сценария scr3 | РЕЗУЛЬТАТЫ и пояснения |
#!/bin/bash clear read a b=$a+1 let c=$a+1 let d=$b+1 echo $a $b echo “ c “ $c “ d “ d echo press key read q | Если сценарий вызвать следующим образом, scr3 то получим следующие результаты. Вводите 3 3 3+1 с 4 d 5 press key |
В сценариях можно использовать управляющие конструкции. Одна из них предполагает использование оператора if. Формат его записи может быть разным, например, таким
If условие
Then
Команды1
Else
Команды 2
fi
В другой форме он записывается так
If условие
Then
Команды
fi
Приведем пример сценария, в котором сравниваются количество файлов в двух каталогах. Этот сценарий надо исполнять в сеансе главного администратора системы - root.
Текст сценария scr4 | РЕЗУЛЬТАТЫ и пояснения |
#!/bin/bash clear echo echo ls1=`ls -a /root | wc -l` echo echo "kol_vo files /root $ls1" echo ls2=`ls -a /home/asplinux | wc -l` echo echo "kol_vo files /home/asplinux $ls3" echo if [ $ls2 -lt $ls1 ]; then echo "/root" fi if [ $ls2 -eq $ls1 ]; then echo "/root" fi if [ $ls2 -gt $ls1 ] then echo "/asplinx" fi echo press key read q | Если сценарий вызвать следующим образом, scr4 то получим следующие результаты. Значение переменной – результат ls kol_vo files /root 22 Значение переменной – результат ls kol_vo files /home/asplinux 31 /asplinux press key |
В операторе if для задания условий могут быть использованы следующие комбинации символов:
|
|
-eq | = | -le | < | -gt | > |
-eq | ¹ | -le | <= | -ge | >= |
В сценариях можно определить такие операции проверки свойств файлов.
-f | файл существует и является обычным | |
-d | является каталогом | |
-h | является символической ссылкой | |
-c | является символьным устройством | |
-b | является блочным устройством | |
-x | является выполняемым файлом | |
-w | файл с разрешением записи | |
-r | файл с разрешением чтения | |
-s | пустой файл (НЕ ПУСТОЙ) |
Условия языка программирования оболочек допускают такие сложные условия:
-o | логическое ИЛИ | |
-a | логическое И | |
! | логическое НЕ |
Для задания сравнения строк используют следующие конструкции:
-n | так проверяют на строковое значение | |
-z | проверка на нулевую строку | |
= | равенство строк | |
!= | неравенство строк |
Приведем другие примеры условного оператора. В следующем сценарии проверяется: «Является ли файл исполнимым?».
Текст сценария scr5 | РЕЗУЛЬТАТЫ и пояснения |
#!/bin/bash clear echo echo if [ -x $0 ]; then echo " execute file $0" fi echo press key read q | Если сценарий вызвать следующим образом, scr5 то получим следующие результаты. execute file scr5 press key |
Такой сценарий проверяет, в каком из двух каталогов (/sbin или /bin) больше ссылочных файлов (-type l).
Текст сценария scr6 | РЕЗУЛЬТАТЫ и пояснения |
#!/bin/bash clear echo echo ls1=`find /bin -type l | wc -l` echo echo "kol_vo files /bin $ls1" echo ls2=`find /sbin -type l | wc -l` echo echo "kol_vo files /sbin $ls2" echo if [ $ls2 -gt $ls3 ] then echo "/bin" fi if [ $ls2 -eq $ls3 ]; then echo "/bin & /sbin" fi if [ $ls2 -lt $ls3 ]; then echo "/sbin" fi echo press key read q | Если сценарий вызвать следующим образом, scr6 то получим следующие результаты. kol_vo files /bin l5 kol_vo files /sbin l7 /sbin press key |
Существует и такая форма оператора if. Она выделяет три случая
|
|
If условие
Then
Команды 1
Elif
Команды 2
Else
Команды 3
fi
В условных конструкциях сценариев можно использовать конструкцию test. Он может быть записан в формате test выражение или [ выражение ]. Последнее является конструкцией, в которой записывается операция сравнения с использованием приведенных выше обозначений. Приведем пример использования test
Текст сценария scr7 | РЕЗУЛЬТАТЫ и пояснения |
#!/bin/bash # 7 clear echo a=test b=TEST c=test test $a = $b echo " test 1 run cod " $? test $a = $c echo " test 2 run cod " $? C1=234 C2=234 [ $C1 -eq $C2 ] echo " test 3 eq " $? [ $C1 = $C2 ] echo " test 4 = " $? let d=$C1 [ $d = 234 ] echo " test 5 = " $? [ $d -eq 234 ] echo " test 6 eq " $? echo press key read q | Если сценарий вызвать следующим образом, scr7 то получим следующие результаты. test 1 run cod 1 test 2 run cod 0 test 3 eq 0 test 4 = 0 test 5 = 0 test 6 eq 0 press key |
В языке сценариев оболочки используются операторы цикла. Они бывают трех типов. Первый из них записывается следующим образом:
Whilе условие
do
Команды
Done
Пример записи оператора цикла в форме whilе для решения задачи вычисления факториала числа 5 может выглядеть так.
Текст сценария scr8 | РЕЗУЛЬТАТЫ и пояснения |
#!/bin/bash let p=5 let i=1 let f=1 while [ $i -le $p ] do let f=f*i let i=i+1 done echo " $p $f" echo echo press key read q | Если сценарий вызвать следующим образом, scr8 то получим следующие результаты. 5 120 press key |
Другая форма записи оператора цикла такая
Until условие
do
Команды
Done
Приведем пример сценария, также реализующего задачу вычисления факториала с использованием until. Обращаем внимание на условие выполнения оператора цикла (-le) в первом случае и условия окончания (-gt) – во втором.
Текст сценария scr9 | РЕЗУЛЬТАТЫ и пояснения |
#!/bin/bash let p=5 let i=1 let f=1 until [ $i -gt $p ] do let f=f*i let i=i+1 done echo " $p $f" echo echo press key read q | Если сценарий вызвать следующим образом, scr9 то получим следующие результаты. 5 120 press key |
Последний вид оператора цикла имеет такой формат записи.
For var in список
do
Команды
Done
При такой записи оператора цикла переменная var последовательно приобретает значения из списка. Цикл выполняется столько раз, сколько элементов в списке. Вместо списка может быть записан шаблон имени файла. Тогда будут перебираться все файлы из текущего каталога, имя которых совпадает с шаблоном. Например, если после in записана *, то цикл выполнится столько раз, сколько файлов в текущем каталоге, а значения переменной var будет последовательно равно именам всех таких файлов
Приведем примеры сценариев с оператором for.
Текст сценария scr10 | РЕЗУЛЬТАТЫ и пояснения |
#!/bin/bash clear echo echo echo "= for 1 =" let l=0 for x in p q r do let l=l+1 echo " $l $x" done echo echo " = for 2 =" echo let l=1 for p in * do echo " $l $p" l=l+1 done echo echo " = for 3 =" echo let l=1 for p in * do if [ -f $p ]; then echo " $l $p" let l=l+1 fi done echo press key read q | Если сценарий вызвать следующим образом, scr10 то получим следующие результаты. = for 1 = Список состоит из трех элементов и будет выполнен три раза. Параметр цикла х приобретет значения из этого списка. 1 p 2 q 3 r = for 2 = 1 scr10 = for 3 = 2 scr10 press key |
Следующая управляющая конструкция реализует структуру множественного выбора. Она записывается следующим образом
Case слово in
Шаблон 1)
Команды
...
;;
Шаблон 2)
Команды
...
;;
*)
Команды
...
;;
Esac
При совпадении значения слово с одним из шаблонов выполняются операторы до двойных символов «;;». Далее сценарий продолжает выполнение со строки после ключевого слова esac.
Текст сценария scr11 | РЕЗУЛЬТАТЫ и пояснения |
#!/bin/bash clear echo case $1 in 0) echo Null;; [1-9]) echo Anoder;; [a|A]) echo a or A;; *) echo NO!!!;; esac echo press key read q | Если сценарий вызвать следующим образом, scr11 С то получим следующие результаты, зависящий от введенного С С => 0 Null C 1 2...9 Anoter C a (A) a or A Другие случаи NO!!! press key |
Задание 39.
1. Создать командный файл, который при выполнении должен получить не менее двух параметров. Если количество переданных сценарию параметров ровно два, то на экране появляются их значения, в противном случае – вывести имя сценария и требование задать два параметра.
2. Создать сценарий, который проверяет наличие строки пользователя (имя пользователя вводится с клавиатуры – команда read ) в файле /ets/passwrd.
3. Создать сценарий, в котором в специально созданную директорию /usr/temp (создать команду mkdir ), копируется файл. Предварительно этот файл создается с клавиатуры командой cat. После создания директории высветить ее содержимое и сделать то же самое после копирования.
4. Создать командный файл, который считывает с клавиатуры имя файла и каталог, а затем копирует указанный файл в заданный каталог.
5. Создать сценарий, который спрашивает имя файла и определяет: имеется ли файл с таким именем в домашнем каталоге пользователя - /home/<имя пользователя>.
6. Создать командный файл, в котором над двумя заданными числами осуществляются следующие действия: эти числа складываются и перемножаются. Затем в цикле на экране распечатывается строки со словом Hello!. Количество строк равно минимальному из заданных чисел.
7. Создать командный файл, который по команде read запрашивает имя каталога и выдает его полное содержимое.
8. Создать командный файл, который по команде read запрашивает имя пользователя и выдает список, запущенных им процессов (вывести такие атрибуты процесса - PID, STAT, COMMAND, TIME, PRI, NI).