355 500 произведений, 25 200 авторов.

Электронная библиотека книг » Дэвид Тейнсли » Linux и UNIX: программирование в shell. Руководство разработчика » Текст книги (страница 14)
Linux и UNIX: программирование в shell. Руководство разработчика
  • Текст добавлен: 15 октября 2016, 00:39

Текст книги "Linux и UNIX: программирование в shell. Руководство разработчика"


Автор книги: Дэвид Тейнсли



сообщить о нарушении

Текущая страница: 14 (всего у книги 25 страниц)

read ANS

if [ "$ANS"="y" ] || [ "$ANS"="Y" ]; then

# да, пользователь желает изменить значение

echo "Enter a sensible value "

read VALUE

#простой тест для уточнения, является ли значение численным,

#добавим к VALUE любое число, проверим код возврата

expr $VALUE + 10 > /dev/null 2>&1

STATUS=$?

# проверим код возврата для expr

if [ "$VALUE"="" ] || [ "$STATUS" != "0" ]; then

# направим ошибки в стандартный поток ошибок

echo " You either entered nothing or a non‑numeric " >&2

echo " Sorry now exiting..counter stays at. $COUNTER" >&2 exit 1 fi

# если мы здесь, значит, это – число, добавим его к COUNTER

COUNTER=`expr $COUNTER + $VALUE`

echo " Counter now set to $COUNTER" else

#если мы здесь, значит, пользователь вместо того, чтобы ввести число,

#нажал клавишу ввода

#или ответим n для изменения значения приглашения

echo " Counter stays at $COUNTER"

fi

Рассмотрим результаты выполнения приведенного сценария.

$ ifcount

Do you wish to change the counter value currently set at 100? [y..n]:n Counter stays at 100

$ ifcount

Do you wish to change the counter value currently set at 100? [y..n]:y

Enter a sensible value: fdg

You either entered nothing or a non‑numeric

Sorry now exiting..counter stays at 100

$ ifcount

Do you wish to change the counter value currently set at 100? [y..n]:y Enter a sensible value: 250

Counter now set to 350

18.3.21. Простой сценарий, обеспечивающий безопасность при регистрации

А теперь рассмотрим структурное дополнение, которое усиливает меры безопасности при регистрации пользователя перед запуском приложений. Поступает приглашение на ввод имени пользователя и пароля; если имя пользователя и пароль

совпадают со строками, включенными в сценарий, пользователь регистрируется. Если

такого совпадения не наблюдается, пользователь завершает работу.

Сценарий устроен так, что вначале переменные получают значение "ложь". Предполагается, что вводные данные пользователя окажутся ошибочными. Текущие установки команды stty сохраняются, поэтому можно скрыть символы, которые вводятся в поле пароля. Затем установки stty восстанавливаются.

Если вводится корректный ID пользователя и пароль (паролем является mayday), переменные invalid_user и invalid_passwd для недействительного пользователя или пароля имеют значение "по". Затем производится тестирование, и если какая‑либо из переменных принимает значение yes, сценарий для этого пользователя завершается по умолчанию.

К работе допускаются пользователи с действительными ID и паролями. В регистрационном сценарии удобно применять описанное структурное дополнение. В данном примере действительными ID пользователя служат dave или pauline.

$ pg ifpass

#!/bin/sh

#ifpass

#установим значения переменных в "ложь" INVALID_USER=yes

INVALID_PASSWD=yes

# сохранение текущих установок команды stty

SAVEDSTTY=`stty -g`

echo "You are logging into a sensitive area"

echo -n "Enter your ID name :"

read NAME

# скройте символы, введенные в терминале

stty -echo

echo "Enter your password :"

read PASSWORD

# попробуем снова

stty $SAVEDSTTY

if [ "$NAME"="dave" ] || [ "$NAME"="pauline" ]; then

# если действительно, установите переменную

INVALID_USER=no

fi

if [ "$PASSWORD"="mayday" ]; then

# если пароль действителен, установите переменную

INVALID_PASSWD=no

fi

if [ "$INVALIDUSER"="yes" -o "$INVALID_PASSWD"="yes" ]; then

echo " `basename $0 :` Sorry wrong password or userid"

exit 1

fi

# если вы здесь, ваш ID и пароль в порядке.

echo "correct user id and password given"

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

$ ifpass

You are logging into a sensitive area

Enter your ID name : dave

Enter your password :

ifpass :Sorry wrong password or userid

Введем верное имя регистрационное имя и пароль.

$ ifpass

You are logging into a sensitive area

Enter your ID name : dave

Enter your password :

correct user id and password given

18.3.22. Применение elif

Часть elif оператора if then else применяется для проверки при наличии более чем двух условий,

18.3.23. Несколько проверок, реализуемых с помощью elif

В следующем несложном примере протестируем введенные в сценарий имена пользователей.

Сначала в сценарии проверяется, действительно ли пользователь ввел имя; если имя не введено, то проверка не выполняется. Если имя введено, с помощью части elif проверяется, совпадает ли имя с root, louise или dave. В случае несовпадения имени ни с одним из перечисленных имен на экран выводится сообщение, что пользователь не является пользователем root, louise или dave.

$ pg ifelif

#!/bin/sh

# ifelif

echo -n "enter your login name :"

read NAME

# имя не введено, рассмотрение прекращается

if [ -z $NAME ] || [ "$NAME"="" ]; then

echo "You did not enter a name"

elif

# является ли именем root

[ "$NAME"="root" ]; then echo "Hello root"

elif

# именем является louise

[ $NAME="louise" ]; then echo "Hello louise"

elif

# именем является dave

[ "$NAME"="dave" ]; then echo "Hello dave"

else

# нет, это какое‑то другое имя

echo "You are not root or louise or dave but hi $NAME"

fi

При выполнении приведенного сценария с использованием различных регистрационных имен получим следующее:

$ ifelif

enter your login name : dave Hello dave

$ ifelif

enter your login name : You did not enter a name

$ ifelif2

enter your login name : peter

You are not root or louise or dave but hi peter

18.3.24. Проверка нескольких вариантов размещения файла

Предположим, что к файлу проверки регистрации требуется применить команду cat. Файл в зависимости от того, кто из пользователей выполнял инсталляцию. находится либо в каталоге /usr/opts/audit/logs, либо в каталоге /usr/Iocal/audit/logs. Перед применением к файлу команды cat следует убедиться в том, что его можно просматривать; именно это и будет уточняться при проверке. Если файл нельзя найти или же его нельзя просматривать, на экран выводится сообщение об ошибке. Ниже приводится соответствующий сценарий:

$ pg ifcataudit

#!/bin/sh

#ifcataudit

#размещение файла регистрации

LOCAT_1=/usr/opts/audit/logs/audit.log

LOCAT_2=/usr/local/audit/audit, logs

if [ -r $LOCAT_1]; then

#если файл находится в этом каталоге и может просматриваться,

#применим к нему команду cat echo "Using L0CAT_1"

cat $LOCAT_1

elif

# иначе, файл должен находиться в этом каталоге и можно его просматривать

[ -r §L0CAT_2 ]

then

echo "Using LOCAT_2"

cat $LOCAT_2

else

# нет ни в одном каталоге…

echo `basename $0`: Sorry the audit file ls not readable or cannot be located." >S2

exit 1

fi

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

$ ifcataudit

ifcataudit: Sorry the audit file ls not readable or cannot be located.

18.4. Оператор case

Оператор case является многовариантным оператором. С его помощью можно искать значения, используя заданный шаблон. Если совпадение с шаблоном установлено, можно выполнять команды, основываясь исключительно на этом соответствии. Ниже приводится формат оператора case:

case значение in шаблон1)

команды1

;;

шаблон2)

команды2

;;

esac

Рассмотрим, как функционирует оператор case. После значения должен находиться предлог "in", а каждый шаблон должен завершаться правой скобкой. В качестве значения может применяться переменная или константа. Когда устанавливается соответствие с шаблоном, для этого шаблона выполняются все команды вплоть до символов ;;.

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

Шаблонная часть может содержать метасимволы. Аналогичным образом соответ–ствие с шаблоном устанавливается при обработке расширений имен файлов в командной строке:

* Произвольные символы

? Произвольный отдельный символ

[. . ] Произвольный символ из класса или диапазона

А теперь рассмотрим несколько примеров.

18.4.1. Простой оператор case

Следующий сценарий отображает приглашение для ввода чисел от 1 до 5. Число передается оператору case, переменной ans присваивается значение ans оператора case, и значение ANS сравнивается с каждым шаблоном.

Если соответствие установлено, команды из шаблонной части выполняются до тех пор, пока не появятся символы ;;. Тогда на экран выводится команда, которая информирует пользователя о сделанном выборе. Затем выполнение оператора case завершается, поскольку совпадение с шаблоном установлено.

Далее выполняются операции, находящиеся после оператора case.

Если соответствие не найдено, с помощью шаблона * выполняется прием всей информации. Затем отображается сообщение об ошибке.

$ pg caseselect

#!/bin/sh

# caseselect

echo -n "enter a number from 1 to 5 :"

read ANS

case $ANS in

1) echo "you select 1"

;;

2) echo "you select 2"

;;

3) echo "you select 3"

;;

4) echo "you select 4"

;;

5) echo "you select 5"

;;

*) echo "`basename $0`: This is not between 1 and 5" >&2

;;

exit 1

esac

Если этот сценарий выполняется с различными вводимыми данными, получим:

$ caseselect

enter a number from 1 to 5 : 4 you select 4

С помощью шаблона * выполним прием информации, с которой не установлено соответствия:

$ caseselect

enter a number from 1 to 5 :pen

caseselect: This ls not between 1 and 5

18.4.2. Применение символа | при поиске по шаблону

При использовании оператора case в качестве команды or можно указывать символ. Например, vt100|vt102) соответствует шаблону vt100 или vt102.

В следующем примере у пользователя запрашивают тип терминала. Если пользователь вводит vt100 или vt102, выполняется сравнение с шаблоном "vtl00| vtl02)". В данном случае переменной term присваивается значение vt100. Если пользователь

указывает тип терминала, который не соответствует шаблону, с помощью шаблона * выполняется прием этой информации и значение типа терминала все равно устанавливается как vt100. Наконец, за пределами действия оператора case производится экспорт переменной term. Независимо от тех сведений, которые вводит пользователь, переменная term представляет действительный тип терминала, поскольку используется поиск по шаблону*.

$ pg caseterm

#!/bin/sh

# caseterm

echo " choices are.. vt100, vtl02, vt220"

echo -n "enter your terminal type :"

read TERMINAL

case $TERMINAL in

vtl00|vt102) TERM=vt100

;;

vt220) TERM=vt220

;;

*) echo "`basename $0`: Unknown response" >&2

;;

echo "setting it to vt100 anyway, so there"

TERM=vt100

esac

export TERM

echo "Your terminal ls set to $TERM"

Если при выполнении сценария указывается некорректный тип терминала, получим следующее:

$ caseterm

choices are.. vt100, vtl02, vt220 enter your terminal type :vt900

caseterm: Unknown response setting it to vt100 anyway, so there

Your terminal ls set to vt100

Если вводится существующий тип терминала, получим:

$ case2

choices are.. vt100, vtl02, vt220 enter your terminal type :vt220

Your terminal ls set to vt220

В любом случае пользователь устанавливает тип терминала.

18.4.3. Приглашение для ввода y или n

Оператор case удобно применять при отображении запроса на продолжение обработки. Ниже приводится сценарий, в котором пользователю предлагается указать в качестве ответа либо 'у', что означает продолжение обработки, либо 'n' – выход из сценария. Если пользователь введет у, Y, yes или Yes, обработка будет продолжена в соответствии с частью сценария после оператора case. Если пользователь введет n, N, no или какой‑либо другой ответ, работа со сценарием для него завершается.

$ pg caseans

#!/bin/sh

# caseans

echo -n "Do you wish to proceed [y..n] :"

read ANS

case $ANS in

y|Y|yes|Yes) echo "yes is selected"

;;

n|N) echo "no is selected"

exit 0 # нет ошибки, поэтому для выхода укажите 0

;;

*) echo "`basename S0`" : Unknown response" >&2

exit 1

;;

esac

# если мы оказались здесь, были выбраны значения y|Y|yes|Yes.

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

$ caseans

Dо you wish to proceed [y..n] :df

caseans : Unknown response

В случае корректного ответа:.

$ caseans

Dо you wish to proceed [y..n] :y

yes is selected

18.4.4. Оператор case и передача командных параметров

Можно также использовать оператор case при передаче параметров в сценарии.

В следующем сценарии при осуществлении проверки используется специальный параметр $#, который представляет число передаваемых аргументов. Если это число отлично от 1, сценарий завершает работу, отображая соответствующее сообщение.

Затем оператор case выполняет прием следующих параметров: passwd, start, stop или help. В дальнейшем код реализуется для каждого совпадения с этими шаблонами. При передаче неизвестного значения на экран выводится стандартное сообщение об ошибке.

$ pg caseparam

#!/bin/sh

# caseparam

if [ $# != 1 ]; then

echo "Usage:`basename $0` [start | stop | help] >&2

exit 1

fi;

# присвойте переменной ОРТ параметр

OPT=$1

case $OPT in

start) echo "starting… `basename $0`"

# здесь коды для начала процесса

;;

stop) echo "stopping..`basenarae $0`"

# здесь колы для прекращения процесса

;;

help)

# здесь находится код для отображения справочной страницы

;;

*) echo "Usage: `basename $0` [start | stop | help]"

;;

esac

Если сценарию передается неверный параметр, получим следующее:

$ caseparam what

Usage:caseparam [start|stop | help]

В случае передачи действительного параметра:

$ caseparam stop

stopping..caseparam

18.4.5. Прием потока ввода без применения шаблонных команд

После шаблонной части необязательно указывать команды; если после шаблонной части команды отсутствуют, до перехода к дальнейшей обработке выполняется фильтрация нежелательных откликов.

Если в отдел учета следует направить отчет об учетной записи, сначала желательно удостовериться, что пользователь правильно ввел номер отдела, а затем уже уточнить, какой отчет выполняется. Такой подход реализуется при сравнении с шаблоном всех требуемых значений; любые другие методы неприемлемы.

В следующем сценарии указано, что если пользователь вводит номер отдела, который не совпадает со значением 234, 453, 655 или 454, то пользователь выйдет из сценария. Если номер отдела указан правильно, аналогичный подход применяется при определении типа отчета. По окончании выполнения оператора case остаются действительный номер отдела и правильный тип отчета. Ниже приводится соответствующий сценарий.

$ pg casevalid

#!/bin/sh

# casevalid

TYPE=""

echo -n "enter the account dept No: :"

read ACC

case $ACC in

234);;

453);;

655);;

454) ;;

*) echo "`basename $0`: Unknown dept No:" >&2

echo "try..234,453,655,454" exit, 1

esac

# если оказались здесь, получен верный номер отдела

echo " 1. post"

echo " 2. prior"

echo -n "enter the type of report: "

read ACC_TYPE

case $ACC_TYPE in

l)TYPE=post;;

2}TYPE=prior;;

*) echo "`basename $0`: Unknown account type." >&2

exit 1

;;

esac

# если оказались здесь, значит все указано правильно!

echo "now running report for dept $ACC for the type $TYPE"

# выполняем отчет о команде.

Если вводимые данные достоверны, получим:

$ casevalid

enter the account dept No: :234

   1. . post

   2. . prior

enter the type of report:2

now running report for dept 234 for the type prior

Если номер отдела введен неверно, получим:

$ casevalid

enter the account dept No: :432

casevalid: Unknown dept No: try..234,453,655,454

При вводе неправильного типа отчета, получим:

$ casevalid

enter the account dept No: :655

   1. . post

   2. . prior

enter the type of report:4

casevalid: Unknown account type.

18.4.6. Значения переменных, заданные по умолчанию

Если при просмотре значения переменной пользователь нажимает клавишу [Return], сценарий завершает работу не всегда. С помощью проверки определяется, установлена ли данная переменная, и если не установлена, то ей может быть присвоено значение.

В следующем сценарии для выполнения отчета пользователю предлагают ввести название дня недели. Если пользователь нажимает клавишу [Return], используется день недели, заданный по умолчанию, а именно "Saturday". Это название и присваивается переменной when.

Если пользователь вводит название другого дня, с помощью оператора case выполняется проверка, совпадает ли введенное название с названием одного из дней недели, предназначенных для выполнения сценария, а именно "Saturday", "Sunday"

и "Monday". Обратите внимание, что всевозможные аббревиатуры названий дней недели составлены так, чтобы выполнялся перехват "всех возможных" комбинаций этих названий.

Ниже приводится соответствующий сценарий.

$ pg caserep

#!/bin/sh

# caserep

echo " Weekly Report"

echo -n "What day do you want to run report [Saturday] :"

#если нажать клавишу ввода, принимается заданное по умолчанию название Saturday

read WHEN

echo "validating..

${WHEN:="Saturday"}"

case $WHEN in Monday|MONDAY|mon);;

Sunday|SUNDAY|sun);;

Saturday|SATURDAY}sat);;

*) echo " Are you nuts!, this report can only be run on " >&2

echo " on a Saturday, Sunday or Monday" >&2

exit 1

esac

echo "Report to run on $WHEN"

# здесь команда для выполнения действительного отчета

При корректных начальных данных получим:

$ caserep

Weekly Report What day do you want to run report [Saturday] : validating..Saturday Report to run on Saturday

Если начальные данные были неправильны, получим:

$ caserep

Weekly Report What day do you want to run report [Saturday] :Tuesday validating..Tuesday

Are you nuts! this report can only be run on a Saturday, Sunday or Monday

Можно заключить, что оператор case функционирует так же, как и несколько операторов if then else. Такой вывод вполне правомерен.

18.5. Цикл for

Общий формат цикла:

for имя_перемениой in list

do

команда1 команда…

done

Цикл for однократно обрабатывает всю информацию для каждого значения, включенного в список list. Чтобы получить доступ к каждому значению в списке, достаточно задать параметр имя_переменной. Командой служит любая действительная команда или оператор интерпретатора shell. В качестве параметра имя_переменной можно указать любое слово.

Применение опции in list не является обязательным; если не включать эту часть, цикл воспользуется позиционными параметрами командной строки.

Опция in list может содержать подстановки, строки и имена файлов. Рассмотрим несколько примеров.

18.5.1. Простой цикл for

Этот цикл просто выводит на экран список, который состоит из " 1 2 3 4 5". Чтобы получить доступ к каждой переменной, в качестве параметра имя_переменной указывается "loop".

$ pg for_i

#!/bin/sh

# for_i

for loop in 1 2 3 4 5

do

echo $LOOP done

Приведенный выше сценарий выводит следующие данные:

$ for_i

1

2

3

4

5

18.5.2. Вывод на экран строки списка

Ниже приводится цикл for, список которого содержит строку значений "orange red blue grey". Для каждой переменной указана команда echo, в качестве параметра имя_переменной указывается loop. Команда echo с помощью части $LOOP выводит на экран каждое значение списка до тех пор, пока список не окажется пустым.

$ pg forlist

#!/bin/sh

# forlist

for LOOP in orange red blue grey

do

echo $LOOP

done

$ forlist

orange

red

blue

grey

Также с помощью цикла имя_переменной можно комбинировать строки (в данном случае речь идет о цикле loop).

echo "this ls the fruit $LOOP"

Результат:

This ls the fruit orange red blue grey

18.5.3. Использование команды ls совместно с циклом for

Этот цикл оценивает команду ls интерпретатора shell и отображает сведения о файлах текущего каталога.

$ pg forls

#!/bin/sh

# forls

for loop in `ls`

do

echo $LOOP

done

$ forls

array

arrows

center

center1

center2

centerb

18.5.4. Применение параметров вместе с циклом for

Если в цикле for опустить часть in list, позиционные параметры командной строки становятся аргументами. Действительно, этот подход аналогичен следующему:

for params in "$@"

или

for params in "$*"

Ниже приводится пример, который показывает, как можно избежать применения конструкции in list. Цикл for обращается к специальному параметру $@ или $* для получения аргументов из командной строки.

$ pg forparam2

#/bin/sh

# forparam2

for params in $*

do

echo "You supplied $params as a command line option"

done

echo $params done

$ forparam2 myfile1 myfile2 myfile3

You supplied myfile1 as a command line option

You supplied myfile2 as a command line option

You supplied myfile3 as a command line option

Следующий сценарий содержит часть in "$@" и образует тот же самый поток вывода, что и предыдущий сценарий.

$ pg forparam3

#!/bin/sh

# forparam3

for params in $@

do

echo "You supplied $params as a command line option"

done

echo $params done

Если развить этот подход далее и осуществлять поиск набора файлов, то совместно с циклом for можно применять команду find . При передаче всех файлов используют преимущество параметра командной строки.

$ pg forfind

#!/bin/sh

# forfind

for LOOP in $@

do

find / -name $LOOP -print

done

Значения передаются с помощью параметра командной строки и образуют часть -name команды find .

$ forfind passwd LPSO.AKSOP

/etc/passwd

/etс/pam.d/passwd

/etc/uucp/passwd

/usr/bin/passwd

/usr/local/accounts/LPSO.AKSOP

18.5.5. Посылка сигналов серверам с помощью цикла for

Поскольку цикл for может обработать каждое слово списка, установим переменную для отображения названий некоторых серверов сети. Воспользуемся циклом for для посылки сигналов каждому из этих серверов.

$ pg forping

#!/bin/sh

# forping

HOSTS=”1itserv dnssevr acctsmain ladpd ladware"

for loop in $HOSTS

do

ping -c 2 $LOOP

done

18.5.6. Создание резервных копий файлов с помощью цикла for

Цикл for можно использовать для создания резервных копий файлов. При этом переменная просто добавляется к целевому аргументу команды ср. Ниже применяется переменная под названием ВАК. Эта переменная добавляется к каждому имени целевого файла при использовании цикла с помощью команды ср. Список включает shell–команду ls.

$ pg forcp

#!/bin/sh

# forcp

BAK=".bak"

for loop in `ls`

do

echo "copying $LOOP to $LOOP$BAK"

cp $LOOP $LOOP$BAK done

$ forcp

copying array to array.bak

copying arrows to arrows.bak

copying center to center.bak

copying center1 to center1.bak

18.5.7. Массовое преобразование

Чтобы найти все файлы, которые начинаются символами "LPSO", и преобразовать их содержимое в символы верхнего регистра, используются команды ls и cat. Команда ls отображает список файлов, а команда cat применяется для передачи списка команде tr. Передаваемые файлы получают расширение UC. Обратите внимание, что при использовании в цикле for команды ls применяются обратные кавычки.

$ pg forUC

#!/bin/sh

# forUC

for files in Us LPSO*'

do

cat $files | tr "[a‑z]" "[A‑Z]" > $files.UC

done

18.5.8. Удаления, выполняемые с помощью редактора sed

В следующем примере для удаления всех пустых строк применяется потоковый редактор sed. Выходной поток данных направляется в новые файлы с расширением .HOLD. Затем команда mv возвращает файлам их исходные имена.

$ pg forsed

#!/bin/sh

# forsed

for files in `ls LPSO*` do

sed -e "/^$/d" $files > $files. HOLD

mv $flies. HOLD $files

done

18.5.9. Подсчет с помощью циклов

При обсуждении команды expr отмечалось, что эта команда применяется, если в циклы необходимо ввести счетчики. Ниже рассматривается пример, в котором цикл for обрабатывает файлы, а вывод и подсчет количества файлов осуществляется с помощью команды ls.

$ pg forcount

#!/bin/sh # forcount counter=0

for files in *

do

# increment

counter=`expr $COUNTER + 1`

done

echo "There are $COUNTER files in `pwd` we need to process"

$ forcount

There are 45 files in /apps/local we need to process

Аналогичный результат можно получить с помощью команды wc.

$ ls |wc -l

45

18.5.10. Циклы for для обработки документов

С циклом for можно комбинировать любые команды. В приведенном примере переменная содержит имена всех зарегистрированных пользователей. Для реализации этой конструкции обращаются к команде who и утилите awk. Затем цикл for обрабатывает имена этих пользователей и каждому высылает электронное сообщение. При отправке сообщения используется конструкция "документ здесь".

$ pg formallit

#!/bin/sh

# formallit

WHOS_ON=`who -u | awk '{print $1}'`

for user in $WHOS_ON

do

mail $user << MAYDAY

Dear Colleagues,

It's my birthday today, see you down the

club at 17:30 for a drink.

See ya.

$LOGNAME

MAYDAY

done

Ниже приводится электронное сообщение для данного сценария.

$ pg mbox

Dear Colleagues,

It's my birthday today, see you down the

club at 17:30 for a drink.

See ya. dave

18.5.11. Вложенные циклы for

Чтобы вложить, циклы, достаточно цикл for поместить в другой цикл:

for имя_переменной in list

do

for имя_переменной2 in list2

do

команда1

done

done

В следующем сценарии представлен вложенный цикл for. Имеются два списка, APPS и SCRIPTS, первый из которых содержит путь к приложениям на сервере, а второй включает административные сценарии, которые выполняются для каждого приложения. Для каждого приложения из списка apps имеется соответствующее название сценария в списке SCRIPTS. Обычно сценарии выполняются в фоновом режиме (с помощью указания префикса &). Данный сценарий посредством команды tee размещает также запись в журнальном файле, поэтому наряду с файлом на экране отображается поток выходных данных. Обратите внимание на выходные данные, чтобы понять, как цикл for использует список SCRIPTS при обработке элементов списка apps.

$ pg audit_run

#!/bin/sh

# audit_run

APPS="/apps/accts /apps/claims /apps/stock /apps/serv"

SCRIPTS="audit.check report.run cleanup"

LOGFILE=audit.log

MY_DATE=`date +%H:%M" on "%d/%m%Y`

# внешний цикл

for loop in $APPS

do

# внутренний цикл

for 1оор2 in $SCRIPTS

do

echo "system $LOOP now running $LOOP2 at $MY_DATE" | tee -a $LOGFILE

$LOOP $LOOP2 &

done

done

$ audit_run

system /apps/accts now running audit.check at 20:33 on 23/051999

system /apps/accts now running report.run at 20:33 on 23/051999

system /apps/accts now running cleanup at 20:33 on 23/051999

system /apps/claims now running audit.check at 20:33 on 23/051999

system /apps/claims now running report.run at 20:33 on 23/051999

system /apps/claims now running cleanup at 20:34 on 23/051999

system /apps/stock now running audit.check at 20:34 on 23/051999

system /apps/stock now running report.run at 20:34 on 23/051999

system /apps/stock now running cleanup at 20:34 on 23/051999

system /apps/serv now running audit.check at 20:34 on 23/051999

system /apps/serv now running report.run at 20:34 on 23/051999

system /apps/serv now running cleanup at 20:34 on 23/051999

18.6. Цикл until

Цикл until позволяет выполнять ряд команд, пока условие остается истинным. Практически цикл until противоположен по смыслу циклу while. Цикл while является более предпочтительным, но в определенных случаях цикл until лучше справляется с работой. Формат цикла until:

until условие

команда1

done

В качестве условия выступает любое действительное проверочное условие. Проверка производится в конце цикла, поэтому в любом случае цикл выполняется однократно – не забывайте об этом обстоятельстве. А теперь рассмотрим несколько примеров.

18.6.1. Простой цикл until

Этот сценарий непрерывно ищет пользователя "root" и выполняет команду who. Результат выполнения команды grep содержится в переменной IS_ROOT.

Если пользователь "root" обнаружен, цикл завершает обработку. Затем пользователю simon направляется электронное сообщение, в котором отмечается, что пользователь "root" зарегистрирован. Обратите внимание на применение команды sleep, которая довольно часто используется в циклах until. Эта команда дает возможность приостановить выполнение цикла на несколько секунд, что позволяет указать дополнительные команды.

$ pg until_who

#!/bin/sh

# until_who

ls_ROOT=`who | grep root`

until [ "$IS_ROOT" ]

do

sleep 5

done

echo "Watch it. roots in " | mail simon

18.6.2. Контроль наличия файла

В этом примере в цикле until выполняется команда "sleep 1" до тех пор, пока не будет удален файл под именем /tmp/monitor. LCK. После удаления файла сценарий продолжает выполняться в обычном режиме.

$ pg until_lck

#!/bin/sh

# until_lck

LOCK_FILE=/trap/process. LCK

until [ ! – f $1OCK_FILE ]

do

sleep 1 done echo "file deleted "

# обычная обработка, файл имеется

В приведенном примере показан один из методов, обеспечивающий совместную работу сценариев при выполнении.

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

Когда выполняется сценарий process_main, создается файл lck (файл блокировки). Приведенный выше сценарий получает информацию, собранную сценарием process_main. Однако он не обрабатывает файл, если сценарий process_main продолжает обновление файла отчета.

Чтобы устранить эти затруднения, сценарий process_main создает файл lck при запуске и удаляет его при завершении работы.

Рассматриваемый сценарий ожидает удаления файла LCK. После того как файл lck удален, сценарий может обрабатывать содержимое файла отчета.

18.6.3. Мониторинг дисковой памяти

Цикл until также полезно применять для контроля состояния системы. Предположим, что необходимо уточнить пространство, занимаемое файлами на диске, и направить пользователю "root" электронное сообщение по достижении определенного уровня.

В следующем сценарии просматривается система файлов /logs. С помощью утилиты awk и команды grep информация постоянно извлекается из переменной $LOOK_out. Значения этой переменной характеризуют объем, занимаемый системой файлов /logs.

Если занятый объем превышает 90%, опция command запускает триггер, пользователю "root" направляется сообщение и сценарий завершает работу. Сценарий следует завершить, поскольку в противном случае, если условие истинно (например, занятый объем по–прежнему превышает 90%(, электронное сообщение пользователю "root" будет высылаться непрерывно.

$ pg until_mon

#!/bin/sh

#until_ mon

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


    Ваша оценка произведения:

Популярные книги за неделю