July 13, 2024 by Sharjeel Aziz6 minutes
Imagine you're working in a Kubernetes environment and need to troubleshoot an issue with a PHP application running in one of your pods. You exec into the pod to investigate, but to your surprise, there are no text editors installed. This is common in container images designed to reduce attack surfaces and resource usage. However, you need to create a PHP file to test some code changes. You can do that with here documents.
The cat << 'EOF' > test.php
command starts a here document. EOF
is the delimiter that indicates the start and end of the document. Using single quotes around EOF
ensures that any variables within the document are not expanded by the shell. The content between << 'EOF'
and EOF
is written to the file test.php
.
The concept of “here documents” originates from the early days of UNIX. Ken Thompson developed the first shell for UNIX called the V6 shell in 1971. The shell introduced a compact syntax for redirection (< >
and >>
) and piping (|
or ^
) that has survived into modern shells. You can also find support for invoking sequential commands (with ;
) and asynchronous commands (with &
). Bash, short for Bourne-Again SHell, developed by Stephen Bourne at Bell Labs, was a replacement for the Thompson shell. This shell incorporated a number of features we use today, including command substitution (using back quotes) and HERE documents to embed preserved string literals within a script. See Evolution of shells in Linux. Early teletype machines had a “here is” key to send RTTY identification (a programmable set of codes) and the term may have originated from that.
Minimum requirements to create here documents:
Here documents are created using shell and require the <<
operator followed by a delimiter. The content of the document is written on the lines that follow, and the document is closed with the delimiter. You can suppress leading tabs by using <<-
Basic syntax: The basic syntax for a here document is as follows:
The delimiter can be any string, commonly EOF
or END
, and it indicates where the content of the here document begins and ends. EOF
(End Of File) is a commonly used marker, but you can use almost any string as a marker, provided it does not appear in the text block.
Preventing variable expansion: To prevent variable expansion, use single quotes around the delimiter.
Redirecting to a file: You can redirect the output of a here document into a file.
The beauty of here documents
lies in their simplicity and flexibility. They are particularly useful in several scenarios, including but not limited to:
Configuration files creation: Quickly create configuration files for software applications directly from the command line.
Scripting: Pass multi-line strings or scripts to languages like Python, PHP, or SQL directly from the shell.
Instructions or notes: Generate files containing instructions, notes, or even templated text without needing an editor.
When working with Kubernetes, you might need to create multiple resources at once. Here documents can help streamline this process:
The -
tells kubectl to read from stdin.
Send email using basic command line tools. In the example below, all the commands will be piped into netcat one by one including the here document.
If you need to process a list of files and add an extension to each one, here documents can help:
Here documents make it easy to generate configuration files without needing a text editor:
In this example of a templated text file, a webapp.config
will be created with values from the environment variables.
You can use here documents to run multiple SQL commands at once:
Here documents can write scripts directly into a file or feed them into an interpreter:
You can pass multi-line input to a function using here documents:
You can make curl display detailed transfer information on stdout using the -w
(write-out) option after a completed transfer. The format is a string that can mix plain text with any number of variables. You can specify this format as a literal string, read it from a file using @filename, or read it from stdin using @-
. The following command is self contained and does not require one to create a separate text file first.
Here’s is an example of a command that fetches the specified URL and prints out various timing details related to the transfer, making it easy to analyze the performance of different stages in the transfer process:
The here document
is an excellent example of the Unix’s philosophy of making complex tasks manageable with simple commands. Whether you’re scripting, managing configuration files, or just need to jot down notes, understanding and utilizing heredocs
can significantly streamline your workflow. Experiment with them, and you’ll soon find them an indispensable part of your command-line toolkit.
References: