Понимание синтаксиса cat << EOF в Bash
Узнайте, как синтаксис cat << EOF создает here documents в bash для перенаправления многострочного ввода. Полное руководство с примерами для SQL-команд и скриптинга.
Как работает синтаксис ‘cat << EOF’ в bash?
Мне нужно было написать скрипт для ввода многострочных данных в программу (psql). После некоторых исследований я обнаружил, что следующий синтаксис работает:
cat << EOF | psql ---params
BEGIN;
pg_dump ----something
update table .... statement ...;
END;
EOF
Это правильно создает многострочную строку (от BEGIN; до END;, включительно) и передает ее как ввод в psql. Однако я не понимаю, как и почему это работает.
Я в основном имею в виду часть ‘cat << EOF’. Я знаю, что ‘>’ выводит в файл, ‘>>’ добавляет в файл, а ‘<’ читает ввод из файла. Что именно делает оператор ‘<<’?
Существует ли страница руководства (man page), которая объясняет этот синтаксис?
Синтаксис cat << EOF в bash создает here document (herедоку), который перенаправляет несколько строк текста в качестве входных данных для команды cat. Оператор << указывает bash читать все между открывающим << EOF и закрывающим разделителем EOF как стандартный ввод для команды, что позволяет создавать многострочные строки непосредственно в вашем скрипте.
Содержание
- Что такое heredoc?
- Как работает оператор
<< - Разбор синтаксиса
- Практические примеры
- Расширенные возможности heredoc
- Альтернативы heredoc
- Типичные случаи использования
Что такое heredoc?
Here document (heredoc) - это метод перенаправления в оболочке, который позволяет передавать несколько строк текста команде. Оператор << делает это возможным. В отличие от обычного перенаправления (>, >>, <), которое работает с файлами, heredoc работает с буквальным текстом, встроенным в ваш скрипт.
cat << EOF
Это строка первая
Это строка вторая
Это строка третья
EOF
В этом примере текст между << EOF и EOF становится входными данными для команды cat, которая затем выводит их в стандартный вывод.
Как работает оператор <<
Оператор << - это оператор перенаправления в оболочке, который указывает bash:
- Читать строки из скрипта до тех пор, пока не встретит слово-разделитель (
EOFв вашем случае) - Рассматривать все эти строки как стандартный ввод для предыдущей команды (
cat) - Продолжить обработку скрипта нормально после строки с разделителем
Ключевое понимание заключается в том, что << создает временный поток ввода из текста, следующего в скрипте, а не из файла или ввода пользователя.
Разбор синтаксиса
Давайте разберем ваш пример:
cat << EOF | psql ---params
BEGIN;
pg_dump ----something
update table .... statement ...;
END;
EOF
cat: Команда, которая получает входные данные<< EOF: Открывает heredoc сEOFв качестве разделителя- Многострочное содержимое: Текст, который становится входными данными для
cat EOF: Разделитель, завершающий heredoc (должен стоять в отдельной строке)| psql ---params: Передает вывод изcatвpsqlчерез канал
Heredoc создает временный поток ввода для cat, который затем передает это содержимое в psql через канал.
Практические примеры
Базовое использование heredoc
# Простой текстовый вывод
cat << EOF
Hello, World!
This is a test.
EOF
# Вывод:
# Hello, World!
# This is a test.
Heredoc с переменными
name="John"
age=25
cat << EOF
My name is $name
I am $age years old
EOF
# Вывод:
# My name is John
# I am 25 years old
Heredoc в вашем примере с psql
Ваше использование идеально подходит для SQL-команд, которые должны выполняться как одна транзакция:
cat << EOF | psql -d mydatabase
BEGIN;
-- Создаем резервную копию
pg_dump -t my_table > backup.sql
-- Обновляем некоторые данные
UPDATE users SET status = 'active' WHERE created_at > '2024-01-01';
-- Завершаем транзакцию
COMMIT;
EOF
Расширенные возможности heredoc
Подстановка переменных
По умолчанию, heredoc выполняет подстановку переменных:
#!/bin/bash
DB_NAME="production"
TABLE_NAME="users"
cat << EOF
Connecting to database: $DB_NAME
Processing table: $TABLE_NAME
EOF
Кавычки для отключения подстановки
Вы можете отключить подстановку переменных, заключив разделитель в кавычки:
#!/bin/bash
DB_NAME="production"
cat << 'EOF'
Database name: $DB_NAME
EOF
# Вывод:
# Database name: $DB_NAME
Отступы в heredoc
Вы можете добавить отступы к содержимому heredoc, если используете <<- (обратите внимание на тире):
#!/bin/bash
if true; then
cat <<- EOF
This is indented
But will be output
Without the leading spaces
EOF
fi
Heredoc с разными разделителями
Разделитель не обязательно должен быть EOF - это может быть любое слово:
cat << SQL_MARKER
SELECT * FROM users;
WHERE status = 'active';
SQL_MARKER
Альтернативы heredoc
Использование printf
Для простых случаев можно использовать printf:
printf "BEGIN;\nUPDATE users SET status = 'active';\nCOMMIT;\n" | psql
Использование here strings
Для однострочного ввода:
psql <<< "BEGIN; UPDATE users SET status = 'active'; COMMIT;"
Использование массивов
Для более сложных сценариев:
sql_commands=(
"BEGIN;"
"UPDATE users SET status = 'active';"
"COMMIT;"
)
printf "%s\n" "${sql_commands[@]}" | psql
Типичные случаи использования
Операции с базами данных
Ваш пример с psql является классическим случаем использования heredoc:
cat << EOF | psql -d myapp
-- Создаем резервную копию
pg_dump -t users > users_backup.sql
-- Очищаем старые данные
TRUNCATE TABLE audit_log;
-- Восстанавливаем из резервной копии
psql myapp < users_backup.sql
-- Создаем отчет
SELECT COUNT(*) FROM users WHERE created_at > NOW() - INTERVAL '7 days';
EOF
Генерация конфигурационных файлов
cat << EOF > /etc/nginx/sites-available/myapp
server {
listen 80;
server_name myapp.com;
root /var/www/myapp;
location / {
try_files \$uri \$uri/ /index.html;
}
}
EOF
Генерация документации
cat << 'EOF' > README.md
# My Application
This application does amazing things.
## Installation
\`\`\`bash
git clone https://github.com/me/myapp
cd myapp
npm install
\`\`\`
EOF
Документация скриптов
#!/bin/bash
<< 'DOCS'
This script automates database backups.
Usage:
./backup.sh [database_name]
Options:
-h, --help Show this help message
-v, --verbose Enable verbose output
DOCS
# Script continues here...
Заключение
Синтаксис cat << EOF - это мощная возможность bash, которая создает here documents (heredoc), позволяя встраивать многострочный текст непосредственно в ваши скрипты. Вот ключевые выводы:
- Оператор
<<создает временный поток ввода из встроенного текста - Разделитель (по умолчанию
EOF) должен стоять в отдельной строке для завершения heredoc - Heredoc идеально подходит для SQL-команд, конфигурационных файлов и документации
- Вы можете контролировать подстановку переменных с помощью кавычек
- Существуют альтернативы, такие как
printfи here strings, для более простых случаев
Для вашего конкретного случая использования с psql, подход с heredoc идеален, так как он позволяет сохранять форматирование SQL и выполнять несколько команд как одну транзакцию. Синтаксис cat << EOF | psql эффективно создает временный SQL-скрипт и передает его напрямую в команду psql.
Для дальнейшего изучения вы можете проверить страницу руководства bash с помощью man bash и найти раздел “REDIRECTIONS”, или поискать “here documents” в документации bash.