Here-doc: многострочный stdin
Когда нужно скормить команде многострочный текст - без создания временного файла:
cat <<EOF > /etc/myapp/config.ini
[server]
host = localhost
port = 8080
user = ${USER}EOF
Всё между <<EOF и закрывающим EOF уходит на stdin команды (тут -
cat, который пишет в файл через >). EOF - просто маркер, можно
использовать любое слово (END, DONE, __SCRIPT__).
Раскрытие переменных: с кавычками или без
По умолчанию ${VAR} и $(...) раскрываются внутри here-doc:
cat <<EOF
Hello, ${USER}!Today is $(date +%F)
EOF
▸Hello, student!
▸Today is 2026-04-29
Если нужен литеральный текст без раскрытия - закавычь маркер:
cat <<'EOF' > script.template
Hello, ${USER}! # ← НЕ раскроется, останется как ${USER}$HOME тоже # ← НЕ раскроется
EOF
Это критично для генерации скриптов / шаблонов / Dockerfile-фрагментов
где $VAR нужны как литеральный текст.
Подавление ведущих табов: <<-
Внутри отступленных блоков (if, function) here-doc выглядит ужасно
потому что отступы попадают в текст. Решение - <<- (минус), bash
обрежет ведущие табы (не пробелы):
if [[ -d /etc ]]; then
cat <<-EOF
это сообщение
с ведущими табами
которые bash обрежет
EOF
fi
Только табы. Если редактор подставляет пробелы - не сработает.
Here-string: <<< для одной строки
Однострочный аналог:
grep apple <<< "i like apple pie"
▸grep читает "i like apple pie" из stdin как из файла
▸эквивалентно: echo "i like..." | grep apple, но БЕЗ pipe и без подпроцесса echo
Полезно для bc, jq, любой команды которая хочет stdin-данные:
bc <<< "2 + 2" # 4
jq '.name' <<< '{"name":"alice"}' # "alice"Типичные ошибки
- Маркер с пробелами в конце - bash не закроет here-doc:
bash
cat <<EOF
text
EOF <-- пробел после EOF! не закроется
<<-с пробелами вместо табов - не сработает обрезание.- Cross-platform:
<<<есть в bash и zsh, в/bin/shнет. Для POSIX-совместимости -printf '...' | cmd.