Command Substitution: Capturing Output with $(...)
What you'll be able to do
- Embed a command result in a sentence with `$(command)`
- Store a command result in a variable with `VAR=$(command)`
- Explain why you wrap it as `"$(...)"`, and how backticks differ
Prerequisites (read these first)
What You'll Learn
- The idea behind command substitution
- How to capture command output into a variable with
$(command) - How
$(...)differs from the older backticks`...` - Why you should wrap it as
"$(...)"with quotes
Words used here
- Variable: a named box that holds a value. Write the name and you get the contents.
- Command substitution: a way to drop a command's output into a line as text. It is sometimes called capturing output.
- Quotes:
"..."are double quotes and'...'are single quotes.
Every command in this article — date, pwd, whoami, ls — only displays things. None of them deletes or edits a file, so a typo cannot damage your computer.
Quick Summary
- Store output in a variable →
VAR=$(command) - Embed output in text →
echo "Today is $(date)" - When in doubt, wrap it in double quotes:
"$(...)"
1. What Is Command Substitution?
Conclusion: Command substitution runs a command and replaces $(...) with its output, inline.
date it prints today's date. I want to use that result inside another command. How do I do that?$(command) and that part gets replaced by the command's output.$(date), the shellAn interactive program that reads the commands you type and runs them. runs date first. It swaps $(date) for the output. Only then does it run the whole command.$ echo "Today is $(date)"
Today is Fri Jun 5 12:00:00 JST 2026
How the replacement works
echo "Today is $(date)"
↓ run date first
echo "Today is Fri Jun 5 ... 2026"The contents of $(...) turn into output-as-text before the outer command runs.
2. Capturing Output into a Variable
Conclusion: Use VAR=$(command) to store output in a variable. No spaces around the = sign.
2-1. The basic form
$ today=$(date +%Y-%m-%d) $ echo "$today"
2026-06-05
today variable now holds the date. That is handy.$ logfile="backup-$today.log" $ echo "$logfile"
backup-2026-06-05.log
2-2. No spaces around =
A variable assignment must have no spaces around the = sign.
today = $(date) # WRONG: shell looks for a command named "today" today=$(date) # correct
With spaces, the shell reads today as a command name. You then get command not found.
3. How It Differs from Backticks
Conclusion: Backticks do the same job, but $(...) nests cleanly and reads better. Prefer it.
`date`. What is that?$(date). Today $(...) is the recommended form.# Old syntax (backticks) $ echo "Today is `date`" # New syntax (recommended) $ echo "Today is $(date)"
Why $(...) is preferred
| Aspect | Backticks `...` |
$(...) |
|---|---|---|
| Nesting | Hard (needs escaping) | Works as-is |
| Readability | Easy to confuse with ' |
Clear brackets |
| Quoting | Quirky | Straightforward |
Understanding backticks is enough for reading older articles. When you write your own, stick to $(...).
4. Nesting Substitutions
Conclusion: You can put $(...) inside $(...). The inner one runs first and feeds the outer.
$ echo "$(basename $(pwd))"
myproject
$(...) inside another $(...). How does that run?$(pwd) becomes the current pathA string that describes the location of a file or directory., say /home/user/myproject.basename takes that and returns only the last part, myproject. basename is the command that strips a path down to its final name.Inside-out flow
basename $(pwd)
↓ run pwd
basename /home/user/myproject
↓ run basename
myprojectWith backticks, you would have to rewrite the inner ones as \`. That rewriting is called escaping, and it is fiddly.
With $(...) you can nest directly. That is its biggest advantage.
5. Why You Should Quote It
Conclusion: Wrapping it as "$(...)" keeps spaces and newlines intact as a single safe value.
5-1. Lina gets stuck: the newlines disappear
$ files=$(ls) $ echo $files # no quotes
Documents Downloads report.txt
$(...) is cut into separate words at every space and newline. That is called word splitting.echo reprints those words with single spaces between them. That is why it looks like one line.$ echo "$files" # with quotes
Documents Downloads report.txt
5-2. When in doubt, quote it
As a rule, wrap substitution results in double quotes: "$(...)".
- File names with spaces will not break
- Newlines are preserved
- An empty result will not make the argument vanish and cause an error
Making "quoteWrapping a string in quote marks (' or ") so it is treated as one single value, e.g. one with spaces in it. it when in doubt" a habit prevents most of the common accidents.
6. Common Beginner Pitfalls
Conclusion: Trailing newlines are stripped, and you can use variables inside $() freely.
6-1. Trailing newlines are stripped
$ count=$(ls | wc -l) $ echo "There are $count files"
There are 3 files
Command substitution removes the trailing newline from the output on its own. That is why you can drop the number straight into a sentence.
6-2. Variables and arguments work inside $()
$ dir=/etc $ echo "Files in $dir: $(ls "$dir" | wc -l)"
Files in /etc: 220
Inside $(...) it is just a normal command line. Variables, pipes, and even other substitutions all work.
6-3. Stay safe when the result is empty
$ result="$(grep "no such word" file.txt)" $ echo "[$result]"
[]
When quoted, an empty search result simply prints [].
Without quotes the argument itself disappears. That is a common cause of unexpected behavior.
7. Mini Exercises
Conclusion: Three tasks — assign, embed, and nest — to practice the basics by hand.
Exercise 1: Store the current user name in a variable called me and print it in a sentence.
Show Hint 1 (Direction)
First run the command that reports your user name. Put the result in a box, then take it back out as part of a sentence.
Show Hint 2 (Command name)
The user name comes from whoami. The form for storing it is name=$(command). Print with echo.
Show Answer
$ me=$(whoami) $ echo "I am $me"
I am lina
The name you see depends on your account.
Exercise 2: Print the sentence "The current directoryA container that organizes files. Same idea as a "folder" on Windows or macOS. is ..." with the output of pwd embedded.
Show Hint 1 (Direction)
No variable this time. Drop the command's output straight into the middle of a sentence.
Show Hint 2 (Command name)
Your location comes from pwd. Wrap the whole sentence in double quotes and insert $(pwd).
Show Answer
$ echo "The current directory is $(pwd)"
The current directory is /home/lina/myproject
The path you see depends on where you are.
Exercise 3: Print only the name of the current directory. That means the last part, not the whole path.
Show Hint 1 (Direction)
Two steps. First get the full path of where you are. Then take only the final name out of that path.
Show Hint 2 (Command name)
The full path comes from pwd. The final name comes from basename. Nest one $(...) inside another.
Show Answer
$ echo "$(basename "$(pwd)")"
myproject
basename takes the path from pwd and returns only its last part. Note that the inner $(pwd) runs first.
8. Review
$(command) replaces that spot with the command's output.VAR=$(command)."$(...)". Without the quotes, word splitting breaks it.$(...) yourself.9. Copy-Paste Templates
Conclusion: Templates for assigning, embedding, naming, and counting — keep them handy.
Handy patterns to keep
# Store output in a variable VAR=$(command) # Embed in a sentence (always double-quote) echo "The result is $(command)" # Build a dated file name logfile="app-$(date +%Y%m%d).log" # Count lines into a variable count=$(ls | wc -l) # Nest substitutions name="$(basename "$(pwd)")"
Today's 3-Line Summary
$(command)replaces that spot with the command's output- To keep the result, write
VAR=$(command). Never put spaces around the= - When you use the result, wrap it as
"$(...)", or spaces and newlines will split it