KnigaRead.com/
KnigaRead.com » Компьютеры и Интернет » Программирование » Мендель Купер - Искусство программирования на языке сценариев командной оболочки

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

На нашем сайте KnigaRead.com Вы можете абсолютно бесплатно читать книгу онлайн Мендель Купер, "Искусство программирования на языке сценариев командной оболочки" бесплатно, без регистрации.
Перейти на страницу:

#!/bin/bash

# logon.sh: Сценарий, написаный "на скорую руку", контролирует вход в режим on-line.


TRUE=1

LOGFILE=/var/log/messages

# Обратите внимание: $LOGFILE должен быть доступен на чтение (chmod 644 /var/log/messages).

TEMPFILE=temp.$$

# "Уникальное" имя для временного файла, где расширение в имени -- это pid процесса-сценария.

KEYWORD=address

# При входе, в файл /var/log/messages,

# добавляется строка "remote IP address xxx.xxx.xxx.xxx"

ONLINE=22

USER_INTERRUPT=13

CHECK_LINES=100

# Количество проверяемых строк.


trap 'rm -f $TEMPFILE; exit $USER_INTERRUPT' TERM INT

# Удалить временный файл, когда сценарий завершает работу по control-c.


echo


while [ $TRUE ] #Бесконечный цикл.

do

tail -$CHECK_LINES $LOGFILE> $TEMPFILE

# Последние 100 строк из системного журнала переписать во временный файл.

# Совершенно необходимо, т.к. новейшие версии ядер генерируют много сообщений при входе.

search=`grep $KEYWORD $TEMPFILE`

# Проверить наличие фразы "address",

# свидетельствующей об успешном входе.


if [ ! -z "$search" ] # Кавычки необходимы, т.к. переменная может содержать пробелы.

then

echo "On-line"

rm -f $TEMPFILE # Удалить временный файл.

exit $ONLINE

else

echo -n "." # ключ -n подавляет вывод символа перевода строки,

# так вы получите непрерывную строку точек.

fi


sleep 1

done


# Обратите внимание: если изменить содержимое переменной KEYWORD

# на "Exit", то сценарий может использоваться для контроля

# неожиданного выхода (logoff).


exit 0


# Nick Drage предложил альтернативный метод:


while true

do ifconfig ppp0 | grep UP 1> /dev/null && echo "соединение установлено" && exit 0

echo -n "." # Печать последовательности точек (.....), пока соединение не будет установлено.

sleep 2

done


# Проблема: Нажатия Control-C может оказаться недостаточным, чтобы завершить этот процесс.

# (Точки продолжают выводиться на экран.)

# Упражнение: Исправьте этот недостаток.


# Stephane Chazelas предложил еще одну альтернативу:


CHECK_INTERVAL=1


while ! tail -1 "$LOGFILE" | grep -q "$KEYWORD"

do echo -n .

sleep $CHECK_INTERVAL

done

echo "On-line"


# Упражнение: Найдите сильные и слабые стороны

# каждого из этих подходов.

Аргумент DEBUG, команды trap, заставляет сценарий выполнять указанное действие после выполнения каждой команды. Это можно использовать для трассировки переменных.

Пример 29-7. Трассировка переменной

#!/bin/bash


trap 'echo "VARIABLE-TRACE> $LINENO: $variable = "$variable""' DEBUG

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


variable=29


echo "Переменная "$variable" инициализирована числом $variable."


let "variable *= 3"

echo "Значение переменной "$variable" увеличено в 3 раза."


# Конструкция "trap 'commands' DEBUG" может оказаться очень полезной

# при отладке больших и сложных скриптов,

# когда размещение множества инструкций "echo $variable"

# может потребовать достаточно большого времени.


# Спасибо Stephane Chazelas.


exit 0


Конструкция trap '' SIGNAL (две одиночных кавычки) -- запрещает SIGNAL для оставшейся части сценария. Конструкция trap SIGNAL -- восстанавливает действие сигнала SIGNAL. Эти конструкции могут использоваться для защиты критических участков сценария от нежелательного прерывания.

trap '' 2 # Сигнал 2 (Control-C) -- запрещен.

command

command

command

trap 2 # Разрешение реакции на Control-C



Глава 30. Необязательные параметры (ключи)

Необязательные параметры -- это дополнительные ключи (опции), которые оказывают влияние на поведение сценария и/или командной оболочки.

Команда set позволяет задавать дополнительные опции прямо внутри сценария. В том месте сценария, где необходимо, чтобы та или иная опция вступила в силу, вставьте такую конструкцию set -o option-name, или в более короткой форме -- set -option-abbrev. Эти две формы записи совершенно идентичны по своему действию.

#!/bin/bash


set -o verbose

# Вывод команд перед их исполнением.


#!/bin/bash


set -v

# Имеет тот же эффект, что и выше.


Для того, чтобы отключить действие той или иной опции, следует вставить конструкцию set +o option-name, или set +option-abbrev.

#!/bin/bash


set -o verbose

# Вывод команд перед их исполнением.

command

...

command


set +o verbose

# Запретить вывод команд перед их исполнением.

command

# команда не выводится.


set -v

# Вывод команд перед их исполнением.

command

...

command


set +v

# Запретить вывод команд перед их исполнением.

command


exit 0


Как вариант установки опций, можно предложить указывать их в заголовке сценария (в строке sha-bang) -- #!.

#!/bin/bash -x

#

# Далее следует текст сценария.


Так же можно указывать дополнительные ключи в командной строке, при запуске сценария. Некоторые из опций работают только если они заданы из командной строки, например -i -- ключ интерактивного режима работы скрипта.

bash -v script-name

bash -o verbose script-name

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

Таблица 30-1. Ключи Bash

Краткое имя Полное имя Описание -C noclobber Предотвращает перезапись файла в операциях перенаправления вывода (не распространяется на конвейеры (каналы) -- >|) -D (нет) Выводит список строк в двойных кавычках, которым предшествует символ $, сам сценарий не исполняется -a allexport Экспорт всех, определенных в сценарии, переменных -b notify Выводит уведомление по завершении фоновой задачи (job) (довольно редко используется в сценариях) -c ... (нет) Читает команды из ... -f noglob Подстановка имен файлов (globbing) запрещена -i interactive Сценарий запускается в интерактивном режиме -p privileged Сценарий запускается как "suid" (осторожно!) -r restricted Сценарий запускается в ограниченном режиме (см. Глава 20). -u nounset При попытке обращения к неопределенным переменным, выдает сообщение об ошибке и прерывает работу сценария -v verbose Выводит на stdout каждую команду прежде, чем она будет исполнена -x xtrace Подобна -v, но выполняет подстановку команд -e errexit Прерывает работу сценария при появлении первой же ошибки (когда команда возвращает ненулевой код завершения) -n noexec Читает команды из сценария, но не исполняет их (проверка синтаксиса) -s stdin Читает команды с устройства stdin -t (нет) Выход после исполнения первой команды - (нет) Конец списка ключей (опций), последующие аргументы будут восприниматься как позиционные параметры. -- (нет) Эквивалент предыдущей опции (-).

Глава 31. Широко распространенные ошибки

Turandot: Gli enigmi sono tre, la morte una!

Caleph: No, no! Gli enigmi sono tre, una la vita!

Puccini

Использование зарезервированных слов и служебных символов в качестве имен переменных.

case=value0 # Может вызвать проблемы.

23skidoo=value1 # Тоже самое.

# Имена переменных, начинающиеся с цифр, зарезервированы командной оболочкой.

# Если имя переменной начинается с символа подчеркивания: _23skidoo=value1, то это не считается ошибкой.


# Однако... если имя переменной состоит из единственного символа подчеркивания, то это ошибка.

_=25

echo $_ # $_ -- это внутренняя переменная.


xyz((!*=value2 # Вызывает серьезные проблемы.


Использование дефиса, и других зарезервированных символов, в именах переменных.

var-1=23

# Вместо такой записи используйте 'var_1'.


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

do_something ()

{

echo "Эта функция должна что-нибудь сделать с "$1"."

}


do_something=do_something


do_something do_something


# Все это будет работать правильно, но слишком уж запутанно.


Использование лишних пробелов. В отличие от других языков программирования, Bash весьма привередлив по отношению к пробелам.

Перейти на страницу:
Прокомментировать
Подтвердите что вы не робот:*