Learn › Linux Foundations › Heredocs
herestring - a hands-on Linux lab on a real virtual machine.
Feed one string to any stdin-reading command with the herestring <<<: no temporary file, no heredoc delimiter. Drilled against cat, grep, wc -w, and tr, plus reading a quiet grep failure with $?, starting a pipeline from a string, and feeding a variable as stdin.
By now you can hand a command a file to read, or pipe another command's output into it. But the input you need is often neither. It is one string, sitting in your head right now: a color list, a word to test, a line to count.
Remember from the heredoc lesson: << feeds a block of lines to a command, and it demands a delimiter word like EOF on its own closing line. That is a lot of ceremony for three words. The shell has a shortcut, exactly one character longer than <<, that skips all of it. By the end of this lesson you will have fed strings to four different tools with it, one line each time, and never touched a file.
The black boxes below are a practice terminal: a safe sandbox that only checks the one command each step teaches, so you cannot break anything. Every drill in this lesson fits on a single line. On the real machine at the end of this module, the heredocs capstone mission has you run these same forms for real.
The shortcut is <<<, the herestring. It feeds one string to a command's stdin, the standard input channel a command reads when you do not hand it a file. Everything after <<< on the same line is the input, and the shell adds a trailing newline for you.
No delimiter word. No body lines. No closing EOF. Where a heredoc is a paragraph, a herestring is a single sentence.
The herestring is the heredoc's younger sibling, in name and in age. It comes from the Korn shell, and bash adopted it in 2002, decades after the heredoc. The name follows the family: a here-document feeds a document, a here-string feeds a string.
Start with cat, which prints whatever it reads. The whole command is:
cat <<< 'a single line of input'
Before you run it, decide: after you press Enter, will the shell wait for a closing line, the way << waits for its delimiter?
prompt: student@linuxcamp:~$ answer: cat <<< 'a single line of input' output: a single line of input hint: cat, a space, the three-character operator, a space, then the string in single quotes.
No wait, no delimiter. The string came straight back and the prompt returned. <<< placed the quoted string on cat's stdin, added a newline on the end, and was done. That is the entire ceremony: none. One string in, one line out.
grep prints the lines of its input that contain a pattern. Feed it a one-line herestring and search for one word:
grep green <<< 'red green blue'
Before you run it, decide: will grep print just the word green, or something more?
prompt: student@linuxcamp:~$ answer: grep green <<< 'red green blue' output: red green blue hint: grep, then the word to search for, then the operator and the quoted three-color string.
It printed the whole line, red green blue, not just the matched word. That is how grep works: a pattern that matches anywhere in a line earns the entire line a place in the output. With a one-line herestring, a match means the whole string comes back. Which raises a question: what does grep do when nothing matches? Hold that thought. You will find out two drills from now.
wc -w counts the words on its input. Here is the drill:
wc -w <<< 'one two three four'
Count the words in that string yourself before you run it. Then let the machine check your answer.
prompt: student@linuxcamp:~$ answer: wc -w <<< 'one two three four' output: 4 hint: wc with the -w flag, then the operator and the quoted four-word string.
4, the count you already had in your head. Nothing else on the line: no filename, because the input came from stdin, not a file. The herestring handed wc four words and wc did its one job.
tr translates characters. Give it a from-range and a to-range, and it converts every matching character on its input. The range 'a-z' into 'A-Z' turns lowercase into uppercase:
tr 'a-z' 'A-Z' <<< 'shout this'
Before you run it, decide exactly what the output line will say.
prompt: student@linuxcamp:~$ answer: tr 'a-z' 'A-Z' <<< 'shout this' output: SHOUT THIS hint: tr, the lowercase range in quotes, the uppercase range in quotes, then the herestring.
SHOUT THIS. Every lowercase letter got translated to its uppercase partner, and the space, which is in neither range, passed through untouched. Note what changed between drills and what did not: cat printed, grep filtered, wc counted, tr transformed, but the herestring did the same quiet job every time. It fills stdin; the command on the left decides the behavior.
Back to the question the grep drill raised: what happens when the word is not there? Search the same string for purple. Remember from the $? lesson: every command leaves an exit status behind, 0 for success and non-zero for failure, and echo $? prints the last one. Chain that read on with a semicolon so you catch the verdict immediately:
grep purple <<< 'red green blue'; echo $?
Before you run it, decide: how many lines will grep itself print, and what number will follow?
prompt: student@linuxcamp:~$ answer: grep purple <<< 'red green blue'; echo $? output: 1 hint: The purple search first, a semicolon, then the two-word command that prints the last exit status.
grep itself printed nothing at all. No match, no output. The single 1 on screen came from echo $?, and it is grep's verdict: 1 means no match. A silent grep is not a broken grep; the answer moved from the screen to the scoreboard. Scripts lean on this constantly, treating grep as a yes-or-no question and reading $? for the answer.
That is the workhorse form mastered. You fed cat, grep, wc, and tr from a herestring, and read a quiet failure through the exit status, without creating a single file.
Three more facts before the training wheels come off. First, a herestring can carry a variable: wrap it in double quotes, as in cat <<< "$name", and the variable's value becomes the input. Second, a herestring can stand at the head of a pipeline: whatever it feeds the first command, a pipe (padded with a space on each side) carries onward. Third, tr can translate more than letter case: tr ' ' '\n' turns every space into a newline, written '\n', which splits words onto their own lines.
The challenges below use all three. No commands are shown from here on. You know every piece.
You watched a failed search score a 1. Now prove the opposite, on one line: search red green blue for the word green, and read the verdict in the same breath. Decide first what both output lines will be.
prompt: student@linuxcamp:~$ answer: grep green <<< 'red green blue'; echo $? output: red green blue 0 hint: The same shape as the purple search, but with the word that really is in the string.
Two lines: the whole matching string, then 0. Put the pair side by side. Success prints its evidence and scores 0; failure prints nothing and scores 1. Same command, same string, and the one-word difference flipped both the output and the verdict.
Take the string gamma alpha beta. Put each word on its own line, in alphabetical order. Two tools, one pipe, one herestring. Decide what the first output line will be before you run it.
prompt: student@linuxcamp:~$ answer: tr ' ' '\n' <<< 'gamma alpha beta' | sort output: alpha beta gamma hint: Translate each space into a newline with tr, feed the string with the herestring, then a padded pipe into the sorting command.
alpha, beta, gamma. One string became three sorted lines: tr split on the spaces, the pipe handed the lines onward, and sort put them in order. The herestring sat at the head of a real pipeline, exactly where a file or another command usually sits.
Last one, from memory. On a single line: store the string hello from a variable in a variable named greeting, then feed that variable to cat with a herestring. Two steps, one semicolon between them.
prompt: student@linuxcamp:~$ answer: greeting='hello from a variable'; cat <<< "$greeting" output: hello from a variable hint: The assignment first, no spaces around the equals sign, a semicolon, then cat and the operator with the dollar-name in double quotes.
The variable's value came out of cat as if you had typed the string yourself. That is the everyday use of a herestring in scripts: a value already lives in a variable, and <<< "$var" hands it to any stdin-reading tool with no temporary file and no extra process. You just drove three drills with no command shown. The operator is yours.
You earned this cheat sheet. Every row is a line you just typed, with output you checked by eye:
The one idea tying the rows together: <<< fills a command's standard input with a single string, no temporary file on disk. Pick << when you have a block of lines (the heredoc lesson), <<- when that block needs tab indenting (the previous lesson), and <<< when you have one string. The next lesson adds the last member of the family: process substitution <(...), which lets a whole command stand in for a file.
Quoting works on a herestring the same way it works everywhere in bash. Single quotes keep the string literal; double quotes let the shell fill in a $variable, which is exactly why the variable challenge needed "$greeting" and not '$greeting'.
Eight one-line commands, one operator. You fed cat, grep, wc, and tr from a herestring, read a quiet failure through $?, started a pipeline from a string, and fed a variable as stdin. All of it without a single temporary file.
The Heredocs module ends with one real Linux machine: the heredocs capstone mission. There a bash VM boots just for you, the tiny team and color files are built for you, and the objectives name goals with no commands shown. You read the objective, recall the operator, and type it. That recall is what makes it stick.
Finish the other Heredocs lessons, then go run every form for real.
Practice The <<< Herestring in a real Linux terminal at The Linux Camp. Progress is verified automatically as you type commands on the machine.