Heredoc - пишем многострочные скрипты без кавычек
Ситуация: вам нужно выполнить несколько команд на удалённом сервере через SSH. Или записать многострочный текст в файл. Или передать длинный SQL-запрос в базу. Оборачивать каждую строку в кавычки и экранировать спецсимволы - утомительно.
Heredoc (встроенный документ) - это конструкция в Bash, которая позволяет передавать многострочный текст как стандартный ввод для команды. И не нужно экранировать кавычки.
Базовый синтаксис:
Вариант 1 (Записать многострочный текст в файл без echo для каждой строки):
Вместо 10 команд
Вариант 2 (Выполнить несколько команд на удалённом сервере через SSH):
Все команды выполняются в одной SSH-сессии, как будто вы зашли на сервер и вводили их вручную.
Вариант 3 (Передать SQL-запрос в psql или mysql):
Вариант 4 (Подавить интерполяцию переменных):
По умолчанию Heredoc подставляет значения переменных. Если нужно, чтобы переменные остались как есть, оберните ограничитель в кавычки:
В файл запишется
Вариант 5 (Подавить ведущие табуляции):
Если в Heredoc есть отступы,
---
Практическое применение #1 (создание скрипта на удалённом сервере):
Практическое применение #2 (генерация конфига nginx из шаблона):
Практическое применение #3 (проверка серии команд на удалённом сервере):
Возможные ошибки:
- Пробел после `<<`: не должно быть пробела между
- Пробел перед EOF: строка с EOF не должна иметь пробелов в начале (если не используется
- Несовпадающий EOF: если открыли
P.S. Есть ещё конструкция `<<< "строка"` - это "встроенная строка". Она передаёт одну строку как стандартный ввод. Например, `bc <<< "2+2"` вместо `echo "2+2" | bc`.
Ситуация: вам нужно выполнить несколько команд на удалённом сервере через SSH. Или записать многострочный текст в файл. Или передать длинный SQL-запрос в базу. Оборачивать каждую строку в кавычки и экранировать спецсимволы - утомительно.
Heredoc (встроенный документ) - это конструкция в Bash, которая позволяет передавать многострочный текст как стандартный ввод для команды. И не нужно экранировать кавычки.
Базовый синтаксис:
command << EOF
строка 1
строка 2
строка 3
EOF
EOF - это метка-ограничитель. Можно использовать любую: END, STOP, BLOCK.Вариант 1 (Записать многострочный текст в файл без echo для каждой строки):
cat > file.txt << EOF
первая строка
вторая строка
третья строка с "кавычками" и $переменными
EOF
Вместо 10 команд
echo - один блок.Вариант 2 (Выполнить несколько команд на удалённом сервере через SSH):
ssh user@server << EOF
cd /var/www
git pull
npm install
pm2 restart app
EOF
Все команды выполняются в одной SSH-сессии, как будто вы зашли на сервер и вводили их вручную.
Вариант 3 (Передать SQL-запрос в psql или mysql):
psql -U user -d dbname << EOF
SELECT * FROM users WHERE created_at > '2025-01-01';
UPDATE users SET status = 'active' WHERE status = 'pending';
EOF
Вариант 4 (Подавить интерполяцию переменных):
По умолчанию Heredoc подставляет значения переменных. Если нужно, чтобы переменные остались как есть, оберните ограничитель в кавычки:
cat > script.sh << 'EOF'
echo "Текущая директория: $PWD"
echo "Пользователь: $USER"
EOF
В файл запишется
$PWD и $USER, а не их значения.Вариант 5 (Подавить ведущие табуляции):
Если в Heredoc есть отступы,
<<- удаляет их:cat > file.txt <<- EOF
строка с отступом
тоже с отступом
EOF
---
Практическое применение #1 (создание скрипта на удалённом сервере):
ssh user@server "cat > /tmp/deploy.sh" << 'EOF'
#!/bin/bash
cd /var/www
git pull origin main
composer install --no-dev
php artisan migrate
EOF
ssh user@server "chmod +x /tmp/deploy.sh && /tmp/deploy.sh"
Практическое применение #2 (генерация конфига nginx из шаблона):
DOMAIN="example.com"
cat > /etc/nginx/sites-available/example.conf << EOF
server {
listen 80;
server_name $DOMAIN;
root /var/www/$DOMAIN;
index index.html;
}
EOF
Практическое применение #3 (проверка серии команд на удалённом сервере):
ssh staging-server << EOF
ps aux | grep nginx
df -h
uptime
EOF
Возможные ошибки:
- Пробел после `<<`: не должно быть пробела между
<< и EOF.- Пробел перед EOF: строка с EOF не должна иметь пробелов в начале (если не используется
<<-).- Несовпадающий EOF: если открыли
<< EOF, закрывать нужно только EOF, не EOF с пробелами.P.S. Есть ещё конструкция `<<< "строка"` - это "встроенная строка". Она передаёт одну строку как стандартный ввод. Например, `bc <<< "2+2"` вместо `echo "2+2" | bc`.
🤝5