Here document (Heredoc) là input hoặc file stream literal được treat như special block of code. Block này passed đến command để processing. Heredoc xuất phát từ UNIX shells, có trong popular Linux shells: sh, tcsh, ksh, bash, zsh, csh. Các ngôn ngữ khác như Perl, Ruby, PHP cũng support heredoc.
Cấu trúc Heredoc
Heredoc dùng 2 angle brackets (<<) theo sau delimiter token. Cùng delimiter token dùng để terminate block. Mọi thứ trong delimiter được consider là block of code.
Ví dụ: redirect block code đến cat command. Delimiter set to "BLOCK" và terminated by cùng "BLOCK".
cat << BLOCK
Hello world
Today date is $(date +%F)
My home directory = ${HOME}
BLOCK
NOTE: Phải dùng same delimiter token start block và terminate block.
Tạo Multiline Comments
Nếu code bash, bạn biết bash default không support multiline comments như C hoặc Java. Dùng HereDoc overcome này.
Đây không phải built-in feature của bash support multi-line comment, chỉ là hack. Nếu không redirect heredoc đến command nào, interpreter chỉ đọc block code và không execute gì.
<< COMMENT
This is comment line 1
This is comment line 2
This is comment line 3
COMMENT
Xử lý White Spaces
Mặc định, heredoc không suppress white space characters (tabs, spaces). Override behavior bằng thêm dash (-) sau (<<) theo sau delimiter. Sẽ suppress all tab spaces nhưng white spaces không suppressed.
cat <<- BLOCK
This line has no whitespace.
This line has 2 white spaces at the beginning.
This line has a single tab.
This line has 2 tabs.
This line has 3 tabs.
BLOCK
Variable và Command Substitution
Heredoc chấp nhận variable substitution. Variables có thể user-defined hoặc environmental variables.
TODAY=$(date +%F)
cat << BLOCK1
# User defined variables
Today date is = ${TODAY}
#Environ Variables
I am running as = ${USER}
My home dir is = ${HOME}
I am using ${SHELL} as my shell
BLOCK1
Tương tự, chạy commands bên trong heredoc code block.
cat << BLOCK2
$(uname -a)
BLOCK2
Escaping Special Characters
Có several ways escape special characters. Character level hoặc doc level.
Escape individual special characters dùng backslash (\).
cat << BLOCK4
\$(uname -a)
BLOCK4
cat << BLOCK5
Today date is = \${TODAY}
BLOCK5
Escape all special characters trong block: surround delimiter với single quotes, double quotes, hoặc prefix delimiter với backslash.
cat << 'BLOCK1'
I am running as = ${USER}
BLOCK1
cat << "BLOCK2"
I am running as = ${USER}
BLOCK2
cat << \BLOCK3
I am running as = ${USER}
BLOCK3
Biết structure heredoc và cách hoạt động, xem vài examples. 2 common areas dùng heredoc: running block commands over SSH và passing SQL queries qua heredoc.
Ví dụ dưới: execute block code remote server qua SSH.
Ví dụ: pass select statement đến psql connect database run query. Alternative way run query trong psql inside bash script thay vì dùng -f flag chạy .sql file.
#!/usr/bin/env bash
UNAME=postgres
DBNAME=testing
psql --username=${UNAME} --password --dbname=${DBNAME} << BLOCK
SELECT * FROM COUNTRIES WHERE region_id = 4;
BLOCK
Đó là tất cả bài viết. Có nhiều hơn bạn có thể làm với heredoc so với examples. Nếu có useful hack với heredoc hãy post comment section để readers benefit.