Linux Basic — Here-Strings

1 minute read

Here-Strings (<<<)

A here-string sends a single string to a command’s standard input. It’s the lightweight cousin of a heredoc — no delimiter, no multi-line body.

grep -o '[0-9]\+' <<< "order #1234 has 7 items"

Output:

1234
7

Why Not Just echo "string" | grep?

Two reasons:

  1. No subshell. A pipe runs the right-hand side in a subshell. Any variables it sets are lost. A here-string runs in the current shell.
  2. No extra process. <<< is built into Bash — no fork of echo.
# pipe — subshell, count is lost
echo "1 2 3" | read a b c
echo "$a"        # empty!

# herestring — same shell, variables persist
read a b c <<< "1 2 3"
echo "$a"        # 1

This is the canonical idiom for parsing a string into fields without a subshell.


Common Patterns

Quick math with bc

result=$(bc -l <<< "scale=4; 22/7")
echo "$result"   # 3.1428

Test a regex with grep

ip="10.20.30.40"
if grep -Eq '^([0-9]{1,3}\.){3}[0-9]{1,3}$' <<< "$ip"; then
    echo "looks like an IP"
fi

Translate characters with tr

tr '[:lower:]' '[:upper:]' <<< "hello world"

Read with a delimiter

IFS=':' read -r user pass uid <<< "alice:secret:1001"
echo "$user $uid"

Variable Expansion

Here-strings expand variables and command substitution just like double quotes:

name="Alice"
cat <<< "Hello $name, the time is $(date +%T)"

If you need literal $, quote it:

cat <<< 'literal $USER'

Here-String vs Heredoc vs Pipe

Form Multi-line Subshell? Best for
cmd <<< "x" no no single string into stdin
cmd <<EOF ... EOF yes no multi-line literal/template
echo x \| cmd no yes (RHS) streaming, real pipelines

Pitfall: Trailing Newline

Here-strings append a newline:

wc -c <<< "abc"   # 4, not 3 (the newline counts)

Use printf '%s' "$x" | cmd if a literal byte count without trailing newline matters.


Next → Process Substitution

Updated: