Apr 09, 2026 • 2 min read
Bash Command Substitution
The Problem
We often use environment variables like $SUBJECT to inject data into commands. But what if that data lives in a file?
Instead of manually copying text, you can use Command Substitution to treat a file’s content as a dynamic variable.
- The example assumes you have a Linux environment.
Technical Solutions
In Bash, there isn’t a direct sigil like $ for files, but you can achieve the same result using Command Substitution. Essentially, you tell Bash to “execute a command that reads the file” and then use the output of that command as the substitution.
There are two general approaches which have minor differences outlined in this blog post:
- Command Substitution
- Built in redirection
Pro-Tip: Dealing with Quotes
-
Just like with variables, if your file contains spaces or special characters and you want to keep them intact, always wrap the substitution in double quotes:
NODE_TYPE // bash# Correct usage: ls "$(< filename.txt)" -
Use Environment Variables for small, frequently accessed flags or secrets.
-
Use File Substitution for larger blocks of text, templates, or data that needs to persist between reboots.
Method One: Command Substitution
-
The Standard Way (Command Substitution) The most common way to do this is using $(cat filename).
-
Create a file subject-1.txt
NODE_TYPE // bashecho "command substitution" > subject-1.txt -
Run the cat command and places the file’s contents directly into your command line.
NODE_TYPE // bash# Command Substitution use: echo "Hello $(cat subject-1.txt)"Expected Output
NODE_TYPE // textHello command substitution
Method Two: Built in redirection
Bash provides a shorthand that is faster because it reads the file directly without spawning an external cat process.
-
The Faster Way (Built-in Redirection)
-
Create a file subject-2.txt
NODE_TYPE // bashecho "built in redirection" > subject-2.txt -
Bash has a shorthand for $(cat …) that is deemed more efficient because it doesn’t need to spawn a new process for the cat command. You simply use < inside the parentheses:
NODE_TYPE // bashecho "Hello $(< subject-2.txt)"Expected Output
NODE_TYPE // textHello built in redirectionNote: This specific syntax is a Bash/Zsh feature and may not work in basic /bin/sh.
Solution Differences
| Feature | Environment Variable ($VAR) | File Substitution ($(< file)) |
|---|---|---|
| Speed | Instant (stored in RAM) | Slower (requires disk I/O) |
| Persistence | Lost when the shell closes | Stays on the hard drive |
| Newlines | Usually treated as a single string | Warning: Shell substitution strips trailing newlines by default |