Европейский Университет в Санкт-Петербурге
Опубликован: 10.10.2005 | Доступ: свободный | Студентов: 1716 / 298 | Оценка: 4.30 / 3.85 | Длительность: 16:22:00
ISBN: 978-5-94774-820-8
Лекция 10:

Командные процессоры

< Лекция 9 || Лекция 10: 123456789

Язык написания скриптов

В командных процессорах используются всего два типа языков. Это sh -подобный язык и csh -подобный язык. Первый тип поддерживается в sh, ksh, bash. Второй - в csh и tcsh. Язык sh более удобен и стандартен, на нем написаны практически все скрипты во всех системах UNIX, включая стартовые скрипты системы. Язык csh по синтаксису ближе к языку программирования С, но используется для скриптов реже. Однако в некоторых случаях программное обеспечение включает в себя скрипты на языке csh, поэтому здесь мы разберем вкратце конструкции обоих языков.

Первой строкой любого скрипта должна быть строка, содержащая управляющий комментарий специального вида:

#!полное_имя_командного процессора

например

#!/bin/sh

Этот комментарий требует выполнить скрипт с помощью указанного командного процессора. По умолчанию скрипт выполняется в среде /bin/sh, даже если он запущен в среде другого командного процессора. Если вы работаете в tcsh и хотите, чтобы ваши скрипты запускались в tcsh, следует обязательно указать полный путь к tcsh в управляющем комментарии.

Язык sh

В языке sh существуют операторы ветвления и циклов. Ниже дано описание этих операторов. В нем жирным шрифтом выделены ключевые слова. Конструкция "команды" подразумевает одну или несколько команд командного процессора или вызовов программ, которые отделяются друг от друга разделителями (точкой с запятой или переводом строки). При вводе многострочных операторов в командной строке, командный процессор начинает новую строку приглашением "продолжение команды" (его вид определяется значением переменной среды окружения PS2 или prompt2 ).

В операторах циклов допустимы команды break (прерывание цикла, управление передается за конец цикла) и continue (передача управления на начало цикла, переход к следующей итерации). Эти команды действуют одинаково в любых командных процессорах, так как они реализованы и в языке sh, и в языке csh.

Оператор ветвления if:

if условие then
		команды
else
		команды
fi

В bash, ksh и новых версиях sh возможна конструкция elseif (вложенное ветвление):

if условие then
		команды
	elseif условие then
команды
	fi
else
		команды
fi

Оператор множественного ветвления case:

case значение_переменной in
значение1) команды; break;
значение2) команды; break;
значение3) команды; break;
*) команды;
esac

Знак "звездочка" ( * ) означает "все остальные значения", т.е. если значение переменной не равно ни значению1, ни значению2, ни значению3.

Операторы цикла while (выполнять, пока условие истинно) и until (выполнять до тех пор, пока условие станет истинным):

while условие do
		команды
done

until условие do
		команды
done

Все эти операторы содержат неотъемлемый элемент, обозначенный нами как условие. Это - вызов любой команды (в том числе другой скрипт или конвейер), возвращающей код завершения.

Условие считается истинным, если код завершения равен нулю, и ложным - если код завершения не равен нулю. Любая программа в UNIX возвращает код завершения: нулевой - в случае успешного выполнения и ненулевой - в противном случае. Значения кодов завершения программ можно выяснить с помощью руководства к ним, например, man.

Для проверки условий, относящихся к объектам файловой системы, применяется программа test. В некоторых командных интерпретаторах есть встроенная команда test, иногда test - это отдельная программа. С помощью test часто проверяется наличие файла или каталога в файловой системе:

if test -e имя_файла then echo <файл существует!>

Язык sh допускает конструкцию [ ] вместо команды test:

if [ -e имя_файла ] then echo <файл существует!>

Эта конструкция эквивалентна вышеприведенной.

С помощью test и [ ] можно проверять различные условия, полный список которых содержится в man test или man sh, man bash.

Некоторые программы всегда возвращают код завершения ноль. Это легко использовать для организации бесконечных циклов. Такие циклы могут понадобиться для перезапуска процессов, имеющих тенденцию к неожиданному и ненужному завершению. Например, так можно запускать процесс pppd для соединения с провайдером по выделенной или коммутируемой линии:

while sleep 10
do
 /usr/sbin/pppd
done

Программа sleep всегда будет возвращать ноль, так что цикл никогда не прервется и будет исправно запускать pppd всякий раз, как только он завершится, например, из-за ошибки связи. Десять секунд ожидания добавлены просто для того, чтобы было время переждать неблагоприятную ситуацию, из-за которой произошла ошибка.

В Solaris и других системах System V такое применение менее полезно, чем в BSD-системах, так как того же эффекта можно добиться, указывая вызов pppd в /etc/inittab с указанием режима запуска respawn (запустить, если завершится).

Оператор for (цикл повторяется для каждого значения из списка):

for имя_переменной in список do
		команды
done

Оператор цикла for используется особенно часто, например, для однотипной модификации нескольких файлов сразу. Предположим, надо во всех файлах *.html в текущем каталоге изменить ссылку на файл с фотографией:

for i in *.html
do
sed 's/otello.gif/dezdemona.gif/g' $i >tmp
mv -f tmp $i
done

Поскольку sed не меняет файл, а лишь выдает измененный текст в свой выходной поток, приходится перенаправлять вывод во временный файл tmp (назовите ваш файл по вкусу, от названия ничего не зависит) и затем переименовать tmp в файл с тем же именем, что у исходного файла. В момент переименования старый файл, естественно, исчезнет.

При вызове sed: следует писать именно $i, а не просто i, чтобы командный процессор подставил в командную строку значение переменной i, а не символ i.

Сразу перенаправить вывод в файл, имя которого указывается как $i, нельзя, поскольку перенаправление вывода в существующий файл вызовет уничтожение его прежнего содержимого. Это значит, что одновременное перенаправление ввода и вывода из/в один и тот же файл недопустимо.

Программе mv дается ключ -f, который требует от нее выполнить работу, не задавая вопросов типа "а вы действительно хотите уничтожить файл?"

Для вывода информации в sh принято использовать команду echo. Эта команда печатает в стандартный выходной поток свои аргументы, а в конце вывода выполняет перевод строки.

Команда

echo -n строка

выводит строку и не добавляет перевод строки в конце.

Для ввода информации в скриптах на языке sh используют оператор read:

read name
echo "Name is $name"

Язык, реализованный в вашем командном процессоре, может быть богаче, чем описанный здесь минимальный стандарт. Для получения дополнительной информации обратитесь к man по вашему командному процессору.

Язык csh

В операторах циклов языка csh можно использовать команды break (прерывание цикла, управление передается за конец цикла) и continue (передача управления на начало цикла, переход к следующей итерации) так же, как и в языке sh.

Языки sh и csh отличаются синтаксисом операторов и некоторыми командами. Помните, что:

  • в csh имена системных переменных среды окружения пишутся буквами нижнего регистра;
  • в csh нет оператора until ; почти все операторы называются иначе, чем в sh.

В csh и tcsh есть свои правила вычисления логических выражений для того, чтобы выяснить истинность или ложность условия в операторах цикла и ветвления. Команда test есть в любом языке, независимо от типа командного процессора:

if (условие)команда

или
if (условие) then
	команды
	else if (условие) then
	команды
	else
		команды
endif

Допускается любое число вложенных операторов elseif, при этом нужен только один оператор endif.

Отступы в операторе ветвления не важны, но операторы else и endif должны начинаться с новой строки, оператор if должен следовать за else или начинаться с новой строки.

Оператор множественного ветвления в csh называется switch:

switch (строка)
		case строка1:
		команды
			breaksw
		case строка2:
		команды
			breaksw
		default:
	команды
			breaksw
endsw

Опреатор switch в csh выполняется подобно оператору switch из языка С, команда breaksw передает управление за оператор endsw.

Оператор while действует так же, как while в sh, однако синтаксис у него немного иной:

while (условие)
	команды
end

Оператор цикла for в csh назвали foreach, подобно одноименному оператору из Perl:

foreach имя_переменной (список)
		команды
end

Если оператор foreach вводится в командной строке, то csh на каждой новой строке выводит приглашение "foreach?" Это означает, что ввод оператора еще не закончен и его можно продолжать, ввод завершается финальным словом end в начале строки.

Для ввода информации в скриптах на языке csh используют конструкцию $< (подстановка строки из входного потока):

echo " Enter your name:" 
setenv name $<
echo "Name is $name"
< Лекция 9 || Лекция 10: 123456789