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

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

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

else exec 7> /dev/null # Подавить вывод.

fi


echo "DEBUG3: beginning" >&${FD_DEBUG3}


ls -l >&5 2>&4 # command1 >&5 2>&4


echo "Done" # command2


echo "sending mail" >&${FD_LOGEVENTS} # Написать "sending mail" в дескр. #7.


exit 0


Глава 17. Встроенные документы

Встроенный документ (here document) является специальной формой перенаправления ввода/вывода, которая позволяет передать список команд интерактивной программе или команде, например ftp, telnet или ex. Конец встроенного документа выделяется "строкой-ограничителем", которая задается с помощью специальной последовательности символов <<. Эта последовательность -- есть перенаправление вывода из файла в программу, напоминает конструкцию interactive-program < command-file, где command-file содержит строки:

command #1

command #2

...


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

#!/bin/bash

interactive-program <<LimitString

command #1

command #2

...

LimitString


В качестве строки-ограничителя должна выбираться такая последовательность символов, которая не будет встречаться в теле "встроенного документа".

Обратите внимание: использование встроенных документов может иногда с успехом применяться и при работе с неинтерактивными командами и утилитами.

Пример 17-1. dummyfile: Создание 2-х строчного файла-заготовки

#!/bin/bash


# Неинтерактивное редактирование файла с помощью 'vi'.

# Эмуляция 'sed'.


E_BADARGS=65


if [ -z "$1" ]

then

echo "Порядок использования: `basename $0` filename"

exit $E_BADARGS

fi


TARGETFILE=$1


# Вставить 2 строки в файл и сохранить.

#--------Начало встроенного документа-----------#

vi $TARGETFILE <<x23LimitStringx23

i

Это строка 1.

Это строка 2.

^[

ZZ

x23LimitStringx23

#----------Конец встроенного документа-----------#


# Обратите внимание: ^[, выше -- это escape-символ

#+ Control-V <Esc>.


# Bram Moolenaar указывает, что этот скрипт может не работать с 'vim',

#+ из-за возможных проблем взаимодействия с терминалом.


exit 0

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

Пример 17-2. broadcast: Передача сообщения всем, работающим в системе, пользователям

#!/bin/bash


wall <<zzz23EndOfMessagezzz23

Пошлите, по электронной почте, ваш заказ на пиццу, системному администратору.

(Добавьте дополнительный доллар, если вы желаете положить на пиццу анчоусы или грибы.)

# Внимание: строки комментария тоже будут переданы команде 'wall' как часть текста.

zzz23EndOfMessagezzz23


# Возможно, более эффективно это может быть сделано так:

# wall <message-file

# Однако, встроенный документ помогает сэкономить ваши силы и время.


exit 0

Пример 17-3. Вывод многострочных сообщений с помощью cat

#!/bin/bash


# Команда 'echo' прекрасно справляется с выводом однострочных сообщений,

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

# Команда 'cat' и встроенный документ помогут вам в этом.


cat <<End-of-message

-------------------------------------

Это первая строка сообщения.

Это вторая строка сообщения.

Это третья строка сообщения.

Это четвертая строка сообщения.

Это последняя строка сообщения.

-------------------------------------

End-of-message


exit 0


#--------------------------------------------

# Команда "exit 0", выше, не позволить исполнить нижележащие строки.


# S.C. отмечает, что следующий код работает точно так же.

echo "-------------------------------------

Это первая строка сообщения.

Это вторая строка сообщения.

Это третья строка сообщения.

Это четвертая строка сообщения.

Это последняя строка сообщения.

-------------------------------------"

# Однако, в этом случае, двойные кавычки в теле сообщения, должны экранироваться.

Если строка-ограничитель встроенного документа начинается с символа - (<<-LimitString), то это приводит к подавлению вывода символов табуляции (но не пробелов). Это может оказаться полезным при форматировании текста сценария для большей удобочитаемости.

Пример 17-4. Вывод многострочных сообщений с подавлением символов табуляции

#!/bin/bash

# То же, что и предыдущий сценарий, но...


# Символ "-", начинающий строку-ограничитель встроенного документа: <<-

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

# но не пробелов.


cat <<-ENDOFMESSAGE

Это первая строка сообщения.

Это вторая строка сообщения.

Это третья строка сообщения.

Это четвертая строка сообщения.

Это последняя строка сообщения.

ENDOFMESSAGE

# Текст, выводимый сценарием, будет смещен влево.

# Ведущие символы табуляции не будут выводиться.


# Вышеприведенные 5 строк текста "сообщения" начинаются с табуляции, а не с пробелов.


exit 0

Встроенные документы поддерживают подстановку команд и параметров. Что позволяет передавать различные параметры в тело встроенного документа.

Пример 17-5. Встроенные документы и подстановка параметров

#!/bin/bash

# Вывод встроенного документа командой 'cat', с использованием подстановки параметров.


# Попробуйте запустить сценарий без аргументов, ./scriptname

# Попробуйте запустить сценарий с одним аргументом, ./scriptname Mortimer

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

# ./scriptname "Mortimer Jones"


CMDLINEPARAM=1 # Минимальное число аргументов командной строки.


if [ $# -ge $CMDLINEPARAM ]

then

NAME=$1 # Если аргументов больше одного,

# то рассматривается только первый.

else

NAME="John Doe" # По-умолчанию, если сценарий запущен без аргументов.

fi


RESPONDENT="автора этого сценария"


cat <<Endofmessage


Привет, $NAME!

Примите поздравления от $RESPONDENT.


# Этот комментарий тоже выводится (почему?).


Endofmessage


# Обратите внимание на то, что пустые строки тоже выводятся.


exit 0

Заключая строку-ограничитель в кавычки или экранируя ее, можно запретить подстановку параметров в теле встроенного документа.

Пример 17-6. Отключение подстановки параметров

#!/bin/bash

# Вывод встроенного документа командой 'cat', с запретом подстановки параметров.


NAME="John Doe"

RESPONDENT="автора этого сценария"


cat <<'Endofmessage'


Привет, $NAME.

Примите поздравления от $RESPONDENT.


Endofmessage


# Подстановка параметров не производится, если строка ограничитель

# заключена в кавычки или экранирована.

# Тот же эффект дают:

# cat <<"Endofmessage"

# cat <<Endofmessage


exit 0

Еще один пример сценария, содержащего встроенный документ и подстановку параметров в его теле.

Пример 17-7. Передача пары файлов во входящий каталог на "Sunsite"

#!/bin/bash

# upload.sh


# Передача пары файлов (Filename.lsm, Filename.tar.gz)

# на Sunsite (ibiblio.org).


E_ARGERROR=65


if [ -z "$1" ]

then

echo "Порядок использования: `basename $0` filename"

exit $E_ARGERROR

fi


Filename=`basename $1` # Отсечь имя файла от пути к нему.


Server="ibiblio.org"

Directory="/incoming/Linux"

# Вообще, эти строки должны бы не "зашиваться" жестко в сценарий,

# а приниматься в виде аргумента из командной строки.


Password="your.e-mail.address" # Измените на свой.


ftp -n $Server <<End-Of-Session

# Ключ -n запрещает автоматическую регистрацию (auto-logon)


user anonymous "$Password"

binary

bell # "Звякнуть" после передачи каждого файла

cd $Directory

put "$Filename.lsm"

put "$Filename.tar.gz"

bye

End-Of-Session


exit 0

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

Пример 17-8. Встроенные документы и функции

#!/bin/bash

# here-function.sh


GetPersonalData ()

{

read firstname

read lastname

read address

read city

read state

read zipcode

} # Это немного напоминает интерактивную функцию, но...


# Передать ввод в функцию.

GetPersonalData <<RECORD001

Bozo

Bozeman

2726 Nondescript Dr.

Baltimore

MD

21226

RECORD001


echo

echo "$firstname $lastname"

echo "$address"

echo "$city, $state $zipcode"

echo


exit 0

Встроенный документ можно передать "пустой команде" :. Такая конструкция, фактически, создает "анонимный" встроенный документ.

Пример 17-9. "Анонимный" Встроенный Документ

#!/bin/bash


: <<TESTVARIABLES

${HOSTNAME?}${USER?}${MAIL?} # Если одна из переменных не определена, то выводится сообщение об ошибке.

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