Искусство программирования на языке сценариев командной оболочки
Шрифт:
Глава 17. Встроенные документы
Встроенный документ (here document) является специальной формой перенаправления ввода/вывода, которая позволяет передать список команд интерактивной программе или команде, например ftp, telnet или ex. Конец встроенного документа выделяется "строкой-ограничителем", которая задается с помощью специальной последовательности символов <<. Эта последовательность --
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
# Текст, выводимый сценарием, будет смещен влево.