Гид по технологиям

Here documents в Bash: полное руководство и шаблоны

8 min read Linux Shell Обновлено 19 Dec 2025
Here documents в Bash: полное руководство
Here documents в Bash: полное руководство

TL;DR

Here documents (heredoc) — это удобный механизм перенаправления многострочного ввода в команды и функции в Bash. Они незаменимы для автоматизации ввода команд на удалённой машине через SSH, генерации файлов и составления писем; при этом важно понимать правила кавычек и экранирования, чтобы контролировать расширение переменных и сохранность табуляции.

Быстрые ссылки

  • Here Documents
  • Основные принципы Here Documents
  • Простые примеры
  • Обработка символов табуляции
  • Перенаправление в файл
  • Передача вывода другой команде (pipe)
  • Передача параметров в функцию
  • Создание и отправка письма
  • Использование с SSH
  • Странное имя, полезные особенности

Скриншот терминала Linux, заглавное изображение

Here documents — это синтаксическая конструкция оболочки, позволяющая передавать многострочный текст через стандартный ввод (stdin) любой команде, которая ожидает ввод. В самых простых случаях это альтернатива echo с множеством строк или созданию временных файлов.

Ключевые моменты в одном предложении:

  • Here document начинается с строки вида: COMMAND << limit_string и заканчивается строкой, содержащей только limit_string.

В одном абзаце, простыми словами: heredoc собирает все строки между начальным маркером и конечным маркером и подаёт их команде как её stdin.

Основные принципы Here Documents

Идиоматическое представление heredoc выглядит так:

COMMAND << limit_string

.
.
text

data

variables

.
.
limit_string

Компоненты:

  • COMMAND: любая команда Linux, принимающая вход через stdin (cat, sed, mail, ssh, собственные функции и т.д.). echo не принимает перенаправлённый stdin.
  • << : оператор перенаправления here document.
  • limit_string: метка, любая строка без пробелов (часто используют EOF, но лучше назвать меткой по смыслу, например _remote_commands).
  • Data List: список строк, который будет поступать в stdin команды до встречи со строкой limit_string.

Советы по читаемости:

  • Используйте осмысленные limit_string вместо EOF: _backup_script, _remote_commands, _config_block.
  • Если в блоке не должны расширяться переменные и выполняться подстановки команд, обрамите limit_string одинарными кавычками: <<’EOF’ или <<’ _EOF’.

Важно: если вы используете кавычки вокруг limit_string (например, “_end_of_text”), содержимое передаётся дословно, без расширения переменных и без подстановки команд.

Примеры и пояснения

Ниже несколько практических примеров — они повторяют базовую демонстрацию и расширяются пояснениями.

Простой пример в командной строке

Если ввести в терминале:

cat << _end_of_text 

и затем строки:

How-To Geek

Review Geek

LifeSavvy

CloudSavvy IT

MindBounce

_end_of_text

то вы увидите, что ничего не было отправлено команде cat до тех пор, пока не встретился маркер _end_of_text. Это демонстрирует, что heredoc собирает ввод целиком и потом подаёт его команде.

Команда here document введена в терминале — приглашение >

И окончательный вывод появится только после закрытия блока:

Вывод here document в терминале

Пример в скрипте с расширением переменных и подстановкой команд

Скрипт heredoc-1.sh:

#!/bin/bash

cat << "_end_of_text"

Your user name is: $(whoami)

Your current working directory is: $PWD

Your Bash version is: $BASH_VERSION

_end_of_text

Сохраните, сделайте исполняемым:

chmod +x heredoc-1.sh

и запустите:

./heredoc-1.sh

Здесь подстановка $(whoami) и расширение $PWD и $BASH_VERSION произойдут до передачи текста в cat. Если вы хотите избежать расширения (показать сами имена переменных), обрамите метку кавычками:

cat <<- "_end_of_text"
...
_end_of_text

В этом случае текст будет передан дословно — переменные не развернутся, подстановок команд не произойдёт.

Обработка символов табуляции

По умолчанию табуляция из heredoc сохраняется. Если heredoc находится внутри отступа (например, внутри блока if или функции), можно использовать <<- (с дефисом) — тогда ведущие символы табуляции будут удалены, но только табуляции (не пробелы).

Пример:

#!/bin/bash

if true; then

    cat <<- _limit_string

    Line 1 with a leading tab.

    Line 2 with a leading tab.

    Line 3 with a leading tab.

_limit_string

fi

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

Перенаправление вывода в файл

Вы можете перенаправить результат выполнения команды, которой передаёте heredoc, в файл — добавив > или >> после первой строки.

Пример heredoc-4.sh, который записывает результат в session.txt:

#!/bin/bash

cat << _end_of_text > session.txt

Your user name is: $(whoami)

Your current working directory is: $PWD

Your Bash version is: $BASH_VERSION

_end_of_text

Запуск ./heredoc-4.sh создаст или перезапишет session.txt.

Передача вывода другой команде (pipe)

Выходной поток команды, принимающей heredoc, можно передать по каналу в другую команду с помощью |

Пример heredoc-5.sh (замена a на e через sed):

#!/bin/bash

cat << _end_of_text | sed 's/a/e/g'

How

To

Gaak

_end_of_text

Результат: Gaak превращается в Geek.

Передача параметров в функцию

Командой при heredoc может быть функция в вашем скрипте. Функция может читать из stdin с помощью read или циклов.

Пример heredoc-6.sh:

#!/bin/bash

# the set_car_details() function

set_car_details ()
{
read make
read model
read new_used
read delivery_collect
read location
read price
}

# The here document that passes the data to set_car_details()

set_car_details << _mars_rover_data

NASA

Perseverance Rover

Used

Collect

Mars (long,lat) 77.451865,18.445161

2.2 billion

_mars_rover_data

# Retrieve the vehicle details

echo "Make: $make"

echo "Model: $model"

echo "New or Used: $new_used"

echo "Delivery or Collection: $delivery_collect"

echo "Location: $location"

echo "Price \$: $price"

Запуск выведет значения, считанные функцией из heredoc.

Вывод скрипта heredoc-6.sh в терминале — данные автомобиля

Создание и отправка письма

Heredoc часто используют для составления многострочных тел писем в локальных MTA (mailx, mail и т.д.). Пример heredoc-7.sh, который использует local mail:

#!/bin/bash

article="Here Documents"

mail -s 'Workload status' dave << _project_report

User name: $(whoami)

Has completed assignment:

Article: $article

_project_report

После запуска письмо появится в локальном почтовом ящике пользователя dave.

Вывод команды mail в терминале — почта пользователя

Использование с SSH

Одно из самых полезных применений heredoc — передача команд в удалённую оболочку по SSH. Если настроены SSH-ключи, процесс может быть полностью автоматизирован.

Пример heredoc-8.sh — подключение к remote-pc и добавление записи в лог на удалённой машине:

#!/bin/bash

ssh -T dave@remote-pc.local << _remote_commands

# do some work in here

# update connection log

echo $USER "-" $(date) >> /home/dave/conn_log/script.log

_remote_commands

Ключевые замечания при использовании heredoc с SSH:

  • Используйте ssh -T, если не нужен псевдотерминал (тогда удалённая оболочка не будет запускать интерактивные настройки).
  • Если внутри heredoc вы используете локальные переменные, подумайте, хотите ли вы, чтобы они развернулись локально до отправки (без кавычек) или чтобы их было видно на удалённой стороне (используйте скобочки и экранирование по необходимости).
  • Для защиты секретов лучше не вставлять пароли прямо в heredoc, а использовать ssh-ключи или агенты.

После запуска вы сможете убедиться, что на удалённой машине появилась запись в /home/dave/conn_log/script.log.

Вывод запуска heredoc-8.sh — подключение SSH

Содержимое файла журнала подключений conn_log/script.log

Когда heredoc не лучший инструмент (краткие контрпримеры)

  • Большие двоичные данные: heredoc передаёт текстовую информацию; для двоичных данных лучше использовать rsync, scp или tar по каналу.
  • Чувствительные секреты: не вставляйте пароли и приватные ключи напрямую в heredoc в общедоступных скриптах.
  • Очень длинные или часто меняющиеся скрипты удалённого выполнения: лучше поддерживать скрипт на удалённой машине и вызывать его по SSH, чем генерировать огромный heredoc каждый раз.
  • Когда требуется интерактивность: некоторые задачи лучше выполнять в интерактивной сессии (tty); использование heredoc с ssh -T отключает псевдотерминал.

Альтернативные подходы

  • Here-strings (<<<): для передачи одной короткой строки удобно использовать:
tr 'a' 'e' <<< "Gaak"
  • Process substitution (<(command)): полезно, когда программа ожидает файл, а вы хотите предоставить вывод команды:
diff <(sort file1) <(sort file2)
  • Использование временных файлов через mktemp и запись в них перед передачей на удалённую машину.
  • Инструменты автоматизации: ansible, fabric, pssh — если нужно управлять множеством хостов и сложной логикой.
  • Expect: для сценариев, требующих автоматического ввода паролей или ответов на интерактивные подсказки.

Методология: как выбрать формат heredoc для задачи

  1. Определите, нужны ли расширения переменных и подстановки команд на локальной стороне.
  2. Если нет — используйте <<’EOF’ (одинарные кавычки) или заключите limit_string в одинарные кавычки.
  3. Если heredoc находится внутри отступа и вы хотите убрать ведущие табуляции — используйте <<-EOF.
  4. Подумайте о безопасности: не вставляйте явные пароли/ключи.
  5. При работе через SSH тестируйте сначала в режиме echo/логирования, затем применяйте в production.

Cheatsheet: шаблоны и полезные сниппеты

  • Дословный heredoc (переменные не разворачиваются):
cat <<'DOC'
This will show $HOME and $(whoami) literally.
DOC
  • Heredoc с удалением ведущих табуляций:
cat <<-EOF
    indented line
EOF
  • Heredoc, отправляемый по SSH (локальные переменные разворачиваются перед отправкой):
ssh user@host << _CMDS
mkdir -p /tmp/some_dir
cat > /tmp/some_dir/config << CONFIG
key=value
CONFIG
_CMDS
  • Запись в файл с перезаписью/добавлением:
cat << EOF > /tmp/out.txt
line1
line2
EOF

cat << EOF >> /tmp/out.txt
more lines
EOF
  • Использование heredoc для создания here-скрипта на удалённой машине:
ssh user@host 'bash -s' <<'REMOTE'
#!/bin/bash
# remote script body
uname -a
REMOTE
  • Передача JSON в команду, которая ожидает stdin:
jq . <

Проверочные сценарии и критерии приёмки

  • Скрипт, использующий heredoc, должен корректно работать при запуске под тем же пользователем и в той же среде.
  • Переменные разворачиваются только если маркер не заключён в одинарные кавычки.
  • При использовании <<- ведущие табуляции должны удаляться, пробелы — сохраняться.
  • При отправке через ssh проверяйте наличие записи/файла на удалённой машине.

Роль-based чек-листы

Для администратора (Sysadmin):

  • Используйте SSH-ключи, не храните пароли в коде.
  • Логируйте изменения и проверяйте журналы на удалённой машине.

Для разработчика (Dev):

  • Выбирайте читаемые limit_string и документируйте ожидания по вводу.
  • Покройте тестами сценарии, где heredoc используется для передачи параметров в функции.

Для SRE/операций:

  • Проверяйте поведение в условиях ошибок сети; добавьте таймауты и ретраи.
  • Не используйте heredoc для огромных данных; используйте rsync/scp.

Безопасность и приватность

  • Никогда не вставляйте секреты в публично доступные скрипты или репозитории.
  • Для секретов предпочитайте SSH-агент, менеджеры секретов (vault) или env-переменные, переданные через безопасные каналы.
  • Если heredoc создаёт временные файлы, применяйте mktemp и устанавливайте строгие права на файлы (chmod 600).
  • При работе с удалённой стороной не отключайте проверки host key (не используйте -o StrictHostKeyChecking=no в production без серьёзных причин).

Maturity levels — когда heredoc подходит и когда нет

  • Уровень 1 (прототип): простой heredoc для быстрой отладки и одноразовых операций.
  • Уровень 2 (скрипты): стабильное использование heredoc в поддерживаемых скриптах с учётом кавычек и безопасности.
  • Уровень 3 (автоматизация): для масштабных деплоев используйте специализированные инструменты (ansible, fabric) вместо большого количества heredoc в одиночных скриптах.

Небольшой плейбук: проверка удалённого дискового пространства и уведомление

Задача: подключиться к remote-pc, проверить свободное место и при нехватке — отправить письмо.

Примерный шаблон:

#!/bin/bash

THRESHOLD=10 # percent free space threshold

ssh -T dave@remote-pc.local << _CHECK
FREE=
free_pct=$(df -h / | awk 'NR==2{print $5}' | tr -d '%')
if [ "$free_pct" -lt $THRESHOLD ]; then
  mail -s 'Low disk space' dave <

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

Частые ошибки и отладка

  • Ошибка: “command not found” внутри heredoc на удалённой машине — проверьте PATH и окружение на той машине.
  • Переменные не разворачиваются — убедитесь, что метка heredoc не заключена в одинарные кавычки.
  • Неправильно удаляются табуляции — <<- удаляет только символы табуляции, не пробелы.
  • Проблемы с кодировкой — убедитесь, что оба хоста используют совместимую кодировку, чаще всего UTF-8.

Заключение

Here documents — простой и гибкий инструмент для передачи многострочного ввода в команды, функции и удалённые оболочки. Правильное использование кавычек, понимание различий между <<, <<- и <<’EOF’, а также осторожное обращение с секретами и большими объёмами данных делают heredoc безопасным и удобным способом автоматизации.

Важно: heredoc — это инструмент; выбирайте его тогда, когда он действительно упрощает задачу: для небольших, управляемых и читаемых блоков ввода. Для более сложных сценариев используйте более подходящие средства автоматизации.

Краткое резюме

  • Here documents позволяют передавать многострочный stdin в команды и функции.
  • Используйте <<’EOF’ для дословного текста, <<-EOF для удаления ведущих табуляций.
  • Для SSH-автоматизации heredoc удобен, но не стоит помещать в него секреты.
Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Что может PDF: советы и рабочие сценарии
Файлы

Что может PDF: советы и рабочие сценарии

Изменить курсор мыши в Windows 11
Windows

Изменить курсор мыши в Windows 11

Как скачать свои данные из TikTok
Конфиденциальность

Как скачать свои данные из TikTok

Таймлапс из автомобиля: как снять на смартфон
Видеосъёмка

Таймлапс из автомобиля: как снять на смартфон

Сменить формат скриншотов на Mac
macOS

Сменить формат скриншотов на Mac

Список дел в Notion — просто и эффективно
Продуктивность

Список дел в Notion — просто и эффективно