Выбрать главу

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

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