Linux Basic — Here-Strings
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:
- 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.
-
No extra process.
<<<is built into Bash — no fork ofecho.
# 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