Смекни!
smekni.com

Администрирование локальных сетей (стр. 4 из 39)

( expr ) Группировка выражений скобками

Ввод данных.

Для ввода иданных в скрипт можно воспользоваться командой

read [parameter …]

которая в качестве аргументов принимает список из одного или более параметров.

Примечание: знак $ перед именем параметра в команде read ставить не нужно.

Циклы.

Очень часто при составлении скриптов простого последовательного выполнения бывает недостаточно. Необходимы механизмы которые позволяли бы выполнять команды с изменяющимися параметрами. Для этих целей шелл предоставляет в распоряжение три цикличекие конструкции: циклы for,while и untill.

Цыкл for

Этот тип циклов позволяет выполнять один и тот же набор команд каждый раз с новыми значениями полученными из списка параметров. Он имеет следующий формат:

for parameter [ in wordlist ]

do command-list

done

где parameter это любое имя параметра, wordlist – один или несколько значений последовательно присваиваемых параметру, command-list – набор команд выполняемых при каждом проходе цикла. wordlist может быть либо просто набором аргументов разделенных пробелом, либо командой шелла которая генерирует сама аргументы. Например следующий скрипт:

for i in 1 2 3 4 5

do

if mkdir $i

then

echo “directory $i was created”

fi

done

создает последовательно директории с именами 1 2 3 4 5 и в случае успешного создания директории выдает сообщение. Следующий скрипт:

for i in `ls a*`

do

cp $i /tmp

echo “$i was copied”

done

копирует все файлы начинающиеся с буквы a из текущего каталога в каталог /tmp.

Цикл while

while command-list1

do command-list2

done

этот цикл запускает команды из списка command-list1, и если последняя команда из списка выполнилась успешно (код возврата равен 0) то начинают выполняться команды из списка command-list2,в противном случае цикл заканчивается. Цикл из следующего примера:

while [ -r $1 ]

do

echo “processing $1”

cat $1 >> summary

shift

done

по очереди считывает аргументы командной строки, в случае когда в текущем каталоге присутствует файл доступный на чтение с именем совпадающим с этим аргументом, содержимое этого файла дописывается к файлу с именем summary. В противном случае, скрипт прекращает свою работу.

Цикл util

until command-list1

do command-list2

done

конструкция этого цикла полностью аналогична циклу while за исключением того что тело цикла (набор команд command-list2) выполняется как минимум один раз не зависимо от успешности выполнения условия цикла (набор команд command-list1).

Оператор case

Оператор case является расширением стандартного условного оператора if. Если есть условие при котором может реализовываться множество вариантов то вместо серии операторов if лучше использовать один case.

case parameter in

pattern1 [ | pattern2 …] ) command-list1 ;;

pattern2 [ | pattern3 …] ) command-list2 ;;

esac

шаблоны pattern определяют варианты параметра parameter. При совпадении параметра с одним из шаблонов будет выполнен соответствующий список команд command-list. В квадратных скобках ([ |pattern2…] ) указаны дополнительные варианты разделенные символом ( | ) которые может принимать parameter помимо основного. Заканчивается список шаблонов скобкой. Более понятней структура этого оператора станет после рассмотрения примера:

case $i in

-d | -c ) mkdir dir1

echo “directory dir1 was created” ;;

-r ) rmdir dir1

echo “directory dir1 was removed” ;;

* ) echo “invalid option” ;;

esac

В этом примере скрипт получив при запуске один из аргументов –d или –c попытается создать директорию с именем dir1 , получив аргумент –r попытается ее стереть. Во всех остальных случаях (шаблон *) он выдаст предупреждение о неправильном аргументе.

Примечание: обратите внимание на то что порядок следования гшаблонов в операторе case имеет большое значение. Так если строку

* ) echo “invalid option” ;;

поставить в самое начало, то на ней будет все время терминироваться скрипт.

Команда . (точка)

Каждый раз когда Вы запускаете шелл программы, создается еще одна копия шелла в которой они выполняются. Поэтому если Вы написали шелл скрипт, то все переменные “живут” только во время выполнения скрипта. Если вы хотите чтобы все переменные из шелл программы были в вашем текущем окружении запускать скрипт нужно в текущем шеле, это достигается использованием команды . (точка).

. scriptname

Команда eval

eval [arg ...]

Аргументы читаються и соединяются в одну команду. Затем эта команда выполняется шеллом и статус выхода команды возвращается как результат команды eval. Если аргументы в команде отсутствуют или пустые то команда возвращает нулевой статус.

В качестве примера рассмотрим два скрипта:

d=’date &’ ; $d

и

d=’eval date &’ ; $d

первый из них не выполнится так как команда date воспримет символ & как аргумент а не как признак запуска в фоновом режиме, в результате чего первый скрипт не выполнится в отличии от второго.

Использование метасимволов.

Во всех конструкциях циклов и операторе case возможно использование метасимволов. Например скрипт из примера оператора цикла for

for i in `ls a*`

do

cp $i /tmp

echo “$i was copied”

done

можно переписать в более простом виде

for i in a*

do

cp $i /tmp

echo “$i was copied”

done

результат будет один и тот же.

2.3.1 Некоторые специальные команды

Разделители && и ||

Это условные разделители. При разделении двух команд с помощью && вторая команда выполнится лишь в том случае когда первая завершится успешно. При разделении команд с помощью || вторая выполнится лишь тогда когда первая закончилась неуспешно (код возврата не равен нулю).

Например при выполнении скрипта:

test –d /usr/tools && cd /usr/tools

test –d /usr/tools || echo “directory doesn’t exist”

вход в директорию /usr/tools будет произведен только при ее наличии, в противном случае будет выдано сообщение о ее отсутствии.

Определение функций

Для сокращения обьема шелл программ и упрощения их понимания и сопровждения шелл допускает введение и использование функций. Для опредения функции используется следующий синтаксис:

name () { list; }

где name – это имя функции, а list – список команд из которых состоит тело функции. Ниже приведен пример функции возвращающей 0 если аргумент переданный ей является директорией и 1 в противном случае.

dir_test () {

if [ -d $1 ]

then

echo “$1 is a directory”

return 0

else

echo “$1 is not directory”

return 1

fi;

}

вызов функции осуществляется следующим образом

name [ parameter … ]

например в нашем случае это можно сделать так

dir_test /usr/bin/sh

Перенаправление ввода-вывода

Как было сказано выше для перенаправления ввода-вывода используються символы (> перенаправление вывода, >> перенаправление вывода с добавлением в файли < перенаправление ввода). Кроме этого существует еще ряд конструкций, одна из которых:

<< [-] word

при этом все линии от первой и до содержащей строчку word будут использоваться как входные данные. Например:

$ cat<<mark

> These words will be printed

> the cat command until the "mark"

> word is found

> mark

These words will be printed

the cat command until the "mark"

word is found

$

Если перед строчкой word стоит минус то все символы табуляции в начале строк будут вырезаны.

Другой часто используемой конструкцией при перенаправлении ввода-вывода является:

<& цифра

>& цифра

При этом задействуется файловый дискриптор ассоциированый с указаной цифрой. В большинстве программ со стандартным вводом связан дискриптор 0, со стандартным выводом дискриптор 1, и со стандартным потоком ошибок дискриптор 2. Все программы которые работают друг с другом через пайпы по умолчанию пользуються дискрипторами 0 и 1. Наиболее часто используемые перенаправления это 1>&2 и 2>&1. Рассмотрим следующий пример из которого станет понятен смысл этих конструкций:

$ ls /no/such/file > out

/no/such/file not found

$ cat out

$

$ ls /no/such/file >out 2>&1

$ cat out

/no/such/file not found

$

первая команда пытается вывести листинг не суцествующего файла перенаправив стандартный вывод в файл out. Файл out при этом оказывется пустым т.к. сообщение об ошибке выводится в стандартный поток ошибок и появляется на терминале. Вторая команда объединяет стандартный поток ошибок со стандартным выводом который перенаправлен в файл out. При этом сообщения об ошибке попадают в файл, о чем свидетельствует команда cat.

Команда exec

exec [arg …]

Эта команда выполняет замещение текущего шела новым шелом или программой. Разница между простым запуском шела и запуском через exec становится очевидной на следующем примере:

$ ksh

$ ps

PID TTY TIME COMMAND

2125 pts/0 0:00 ksh

2094 pts/0 0:00 sh

2126 pts/0 0:00 ps

$

$ exec ksh

$ ps

PID TTY TIME COMMAND

2127 pts/0 0:00 ps

2094 pts/0 0:00 ksh

$

Команда expr

expr expression { +, -, &bsol;*, /, *, =, &bsol;>, &bsol;>=, &bsol;<, &bsol;<=, != } expression

Это очень полезная команда для выполнения арифметических операций в шелл скриптах. Например:

x=10

expr $x + 5

y=`expr $x – 10`

if expr $x &bsol;<= $y

then

echo “$x is less or equal than $y”

fi

Команда set

Эта команда используется во многих модификациях. Основное назначение – это устанавливать значение параметров. Если Вы просто запустите эту команду без аргументов то увидите все параметры вашего окружения, большинство из которых было установлено при входе в систему из файла .profile.

Наример команда:

set bob brr kab ram

установит параметры $1, $2, $3, $4 следующим образом $1=”bob”, $2=”brr”, $3=”kab”, $4=”ram”. Команда set имеет множество опций, полный список которых можно получить обратившись к man-странице (man set).

Команда trap

Команда trap ожидает приход сигналов посланных шелу (от внешних процессов или сигнал от шела вследствии неуспешного запуска программы) и выполняет их обработку.

trap [command_list] [s1 …]

Когда trap получает сигнал s1 (сигналы s2 …) она выполняет список заранее предопределенных в command_list команд. Если s1 равен 0, то команды запускаются когда шелл заканчивает свою работу. Команда trap запущенная без аргументов выдает на печать список команд ассоциированных с каждым из номеров сигналов. Ниже приведен краткий список наиболее часто используеиых сигналов.