cat <
Привет, $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 <
# Ключ -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 <
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
: <
${HOSTNAME?}${USER?}${MAIL?} # Если одна из переменных не определена, то выводится сообщение об ошибке.
TESTVARIABLES
exit 0
Подобную технику можно использовать для создания "блочных комментариев".
Пример 17-10. Блочный комментарий
#!/bin/bash
# commentblock.sh
: << COMMENTBLOCK
echo "Эта строка не будет выведена."
Эта строка комментария не начинается с символа "#".
Это еще одна строка комментария, которая начинается не с символа "#".
&*@!!++=
Эта строка не вызовет ошибки,
поскольку Bash проигнорирует ее.
COMMENTBLOCK
echo "Код завершения \"COMMENTBLOCK\" = $?." # 0
# Показывает, что ошибок не возникало.
# Такая методика создания блочных комментариев
#+ может использоваться для комментирования блоков кода во время отладки.
# Это экономит силы и время, т.к. не нужно втавлять символ "#" в начале каждой строки,
#+ а затем удалять их.
: << DEBUGXXX
for file in *
do
cat "$file"
done
DEBUGXXX
exit 0
Еще одно остроумное применение встроенных документов -- встроенная справка к сценарию.
Пример 17-11. Встроенная справка к сценарию
#!/bin/bash
# self-document.sh: сценарий со встроенной справкой
# Модификация сценария "colm.sh".
DOC_REQUEST=70
if [ "$1" = "-h" -o "$1" = "--help" ] # Request help.
then
echo; echo "Порядок использования: $0 [directory-name]"; echo
sed --silent -e '/DOCUMENTATIONXX$/,/^DOCUMENTATION/p' "$0" |
sed -e '/DOCUMENTATIONXX/d'; exit $DOC_REQUEST; fi
: << DOCUMENTATIONXX
Сценарий выводит сведения о заданном каталоге в виде таблице.
-------------------------------------------------------------
Сценарию необходимо передать имя каталога. Если каталог не
указан или он недоступен для чтения, то выводятся сведения
о текущем каталоге.
DOCUMENTATIONXX
if [ -z "$1" -o ! -r "$1" ]
then
directory=.
else
directory="$1"
fi
echo "Сведения о каталоге "$directory":"; echo
(printf "PERMISSIONS LINKS OWNER GROUP SIZE MONTH DAY HH:MM PROG-NAME\n" \
; ls -l "$directory" | sed 1d) | column -t
exit 0
Для встроенных документов, во время исполнения, создаются временные файлы, но эти файлы удаляются после открытия и недоступны для других процессов.
bash$ bash -c 'lsof -a -p $$ -d0' << EOF
> EOF
lsof 1213 bozo 0r REG 3,5 0 30386 /tmp/t1213-0-sh (deleted)
Некоторые утилиты не могут работать внутри встроенных документов .
Читать дальше