Bash Redirection Trick Replaces echo? Explained
The calculator for this page is switched off while it is checked. The formula is below, and the worked example in the article shows how to use it by hand.
Yes, a here-string (<<<) or here-document (<<) can replace echo in many Bash redirection scenarios, but not all. This trick lets you feed a string directly into a command's standard input without spawning a separate echo process, which is faster and often cleaner in scripts. Below, we break down exactly how it works, when to use it, and where echo is still the better choice.
Formula
The here-string syntax is <<< "text" or <<< "$variable". It expands variables and command substitutions just like a double-quoted string, then appends a newline and feeds the result to the command’s stdin. The formula in words: command <<< “string” is equivalent to echo “string” | command for most commands that read from stdin.
Variables: command is any program that accepts input on standard input; string is the text or variable you want to pass. No units apply here.
Worked Example
Using the default from the calculator above, with input text “Hello world” and repeat count 1, the here-string equivalent is:
- Start with the text:
Hello world - Expand any variables or commands (none here).
- Append a newline automatically.
- Feed to a command like
cat:cat <<< "Hello world"
The output is Hello world followed by a newline, exactly what echo "Hello world" | cat would produce.
What Is a Here-String?
A here-string is a Bash feature that sends a single line of text to a command’s standard input. It was introduced in Bash 2.05b (around 2002) and is available in all modern versions of Bash, Zsh, and Ksh. The syntax is three less-than signs followed by a space and the string: <<< "text". The shell performs word splitting, globbing, and variable expansion on the text before sending it, just like a double-quoted string. It always adds a trailing newline, which is usually what you want for line-oriented commands like grep, sed, or awk.
The main advantage over echo is that you avoid creating a subshell and a pipe. In a tight loop with thousands of iterations, that saves measurable time. It also avoids subtle quoting bugs: echo "$var" | command can break if $var starts with a dash (echo might interpret it as an option) or contains escape sequences that echo processes (like \n). Here-strings pass the text literally after expansion.
When to Use a Here-Document Instead
For multi-line input, a here-document (<< EOF) is the better replacement for echo. It allows you to embed newlines directly in the script:
cat << EOF Line 1 Line 2 EOF
This sends two lines to cat without using echo. Here-docs also support variable expansion unless you quote the delimiter (e.g., << 'EOF' to suppress expansion). Use a here-doc when you need more than one line, and a here-string when you have a single line or a variable that may contain newlines (the here-string will still pass them, but the syntax is cleaner for one-liners).
Common Problems and Pitfalls
- Missing space after <<<:
cat <<<"text"works, butcat <<<"text"without a space is fine; the issue is when you writecat <<<textwithout quotes and the text contains spaces—then it splits into multiple arguments. Always quote the string or use a variable. - Trailing newline added: If you need to pass a string without a newline (e.g., to a program that reads a single byte), a here-string won’t work; use
printfinstead. - Not POSIX: Here-strings are not part of the POSIX shell standard. If you’re writing a script for
sh(dash on Debian/Ubuntu), it will fail. Useecho | commandor a here-doc for portability. - Command substitution side effects: The text inside a here-string is expanded, so if you have a literal
$or backtick, you must escape it or use single quotes around the delimiter in a here-doc.
Here-String vs. Echo in Practice
Let’s compare common uses:
- Piping to grep:
echo "error" | grep errorvs.grep error <<< "error"— both work, but the here-string avoids a pipe. - Passing a variable:
echo "$var" | wc -cvs.wc -c <<< "$var"— note that here-string adds a newline, sowc -cwill count one more character than echo (unless echo also adds a newline, which it does by default). This is a common gotcha. - Reading from stdin:
read line <<< "$var"is a classic way to split a string into a variable without a pipe (which would run in a subshell). This is a genuine replacement forecho "$var" | read line, which doesn’t work as expected because the read happens in a subshell.
In short, use a here-string when you need to feed a single string to a command’s stdin and you want to avoid a subshell or quoting issues. Use echo when you’re writing for POSIX sh, when you need to output to the terminal (not stdin), or when you need to control the exact bytes (use printf for that).
Performance and Portability
In Bash, a here-string is a shell built-in, so it’s faster than forking an external echo command and setting up a pipe. For a single use, the difference is negligible, but in loops with thousands of iterations, it can shave seconds. However, if you need POSIX compliance, stick with echo or printf. Also note that in Zsh, here-strings work the same, but in older versions of Ksh, there were quirks with word splitting; modern Ksh93 handles them fine.
Another portability concern: the here-string always appends a newline. If you need to pass a string without a newline, use printf '%s' "$var" | command. This is a common misconception that here-strings are byte-identical to echo; they are not when echo is invoked with -n.
Frequently Asked Questions
Can I use a here-string to replace echo in all cases?
No. Here-strings only send data to standard input. If you need to output to stdout (like echo hello to display on the terminal), you can’t replace that with a here-string. Also, if you need to pass multiple arguments to a command, echo can do that (e.g., echo a b c), but a here-string sends one string. For those cases, keep echo.
Does a here-string add a newline?
Yes, it always appends a newline to the string. This is usually what you want for commands like read or grep, but it can cause off-by-one errors with wc -c or wc -m. If you need no newline, use printf.
Is there a difference between <<< and <<?
Yes. <<< is a here-string for a single line. << starts a here-document that continues until a delimiter line. Here-docs are for multi-line input and can be quoted to prevent expansion. Here-strings are just a shorthand for a one-line here-doc.
Why does echo "$var" | read x not work in Bash?
Because the pipe creates a subshell, so the read command sets the variable in the subshell, not in the current shell. Using read x <<< "$var" runs read in the current shell, so the variable is set correctly. This is a classic use case for here-strings.
Can I use a here-string with sudo?
Yes, but be careful. sudo command <<< "password" will send the password to the command’s stdin, which is not what sudo expects (it reads from the terminal). For sudo, you should use sudo -S to read from stdin, but that’s a separate topic. In general, avoid sending sensitive data via here-strings because they appear in process listings.
What is the POSIX-compliant alternative?
For POSIX sh, use printf '%s\n' "$var" | command or a here-document. Here-strings are not POSIX, so if you need portability to dash or other minimal shells, avoid them.
Related
Formula used
in t | Input text | - | Hello world | 0 in n | Repeat count | - | 1 | 1 out r | Repeated text | - | t | 0
Each line is one input (in, sel, list) or one result (out: label, unit, formula, decimals). How the calculators work
Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.