Bash Heredoc

При написании shell-скриптов может понадобиться передать многострочный блок текста или кода в интерактивную команду, такую как tee, cat или sftp.

Bash Heredoc

В Bash и других оболочках (например, Zsh) here-document (heredoc) — это форма перенаправления, которая позволяет передавать несколько строк ввода команде.

[КОМАНДА] <<[-] РАЗДЕЛИТЕЛЬ
  HERE-DOCUMENT
РАЗДЕЛИТЕЛЬ
  • Первая строка начинается с необязательной команды, оператора << и идентификатора-разделителя.

    • Любая строка может быть разделителем; часто используют EOF или END.
    • Если разделитель не в кавычках (' или "), выполняется подстановка переменных, подстановка команд и т.д.
    • Использование <<- заставляет оболочку удалять начальные табуляции из here-документа (пробелы не удаляются).
  • Последняя строка должна содержать только разделитель (без начальных пробелов или символов в конце).

Примеры heredoc

Вывод с переменными

Heredoc чаще всего используется с cat.

cat << EOF
Текущий рабочий каталог: $PWD
Вы вошли как: $(whoami)
EOF

Получим:

Текущий рабочий каталог: /home/linuxize
Вы вошли как: linuxize

Без подстановки переменных

Кавычки вокруг разделителя отключают подстановку:

cat << "EOF"
Текущий рабочий каталог: $PWD
Вы вошли как: $(whoami)
EOF

Получим:

Текущий рабочий каталог: $PWD
Вы вошли как: $(whoami)

С отступами в условии

Можно использовать операцию перенаправления <<-, она позволяет задавать левый отступ в коде.

Это может быть полезно, когда heredoc находится внутри оператора или цикла, где хорошо бы добавить левый-отступ к коду:

if true; then
	cat <<- EOF
	Строка с начальной табуляцией.
	EOF
fi

Запись в переменную

Простой пример:

COMMAND=$(cat << BASH
your command here
BASH
)

Еще пример с использованием переменных:

DB_USER=db_user
DB_NAME=db_name
DB_PASSWORD=db_pass

COMMAND=$(cat << BASH
mysql -u "$DB_USER" -p"$DB_PASSWORD" -e "USE $DB_NAME;" 2>/dev/null
if ! \$?; then
	mysql -u "$DB_USER" -p"$DB_PASSWORD" -e "CREATE DATABASE $DB_NAME;"
fi
BASH
)

echo "$COMMAND"

Получим:

mysql -u "db_user" -p"db_pass" -e "USE db_name;" 2>/dev/null
if ! $?; then
	mysql -u "db_user" -p"db_pass" -e "CREATE DATABASE db_name;"
fi

Запись в файл

Вместо вывода на экран вы можете перенаправить его в файл, используя операторы >, >>. Если файл file.txt не существует, он будет создан. При использовании > файл будет перезаписан, тогда как >> добавит вывод в конец файла:

cat << EOF > file.txt
Текущий рабочий каталог: $PWD
Вы вошли как: $(whoami)
EOF

Пайп в sed или запись в файл

Ввод heredoc также может быть направлен в конвейер (пайп, |). В следующем примере команда sed заменит все вхождения символа l на e:

cat <<'EOF' | sed 's/l/e/g'
Hello
World
EOF

Получим:

Heeeo
Wored

Запись данных из конвейера в файл:

cat <<'EOF' | sed 's/l/e/g' > file.txt
Hello
World
EOF

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

Использование Heredoc — один из самых удобных и простых способов выполнить несколько команд на удалённой системе через SSH.

При использовании разделителя без кавычек убедитесь, что вы экранируете все переменные, команды и специальные символы, иначе они будут интерполированы локально:

ssh -T user@host.com << EOF
echo "Локальный рабочий каталог: $PWD"
echo "Удалённый рабочий каталог: \$PWD"
EOF

Получим:

Локальный рабочий каталог: /home/linuxize
Удалённый рабочий каталог: /home/user

Заключение

Heredoc, here-document, здесь-док, многострочный ввод Bash, перенаправление «<<EOF», оператор «<<-», вставка блоков текста, скрипт Linux, shell-скриптинг, автоматизация команд, cat tee ssh sed, вывод в файл, переменные в here-doc, удаление табов, примеры heredoc в bash-скриптах, передача кода, командная строка Linux, scripting tips, bash heredoc examples, EOF delimiter, многострочная строка в shell, вывод без интерполяции, <<'EOF', pipe в sed, SSH remote commands, удобная вставка текста, Linux CLI.

--

Источник: https://linuxize.com/post/bash-heredoc/