Quoting, Variables, and Command Substitution
Learn the difference between single and double quotes, how to escape special characters, and how to capture the output of one command inside another.
What the shell does before it runs a command
Before running your command, the shell rewrites it. It replaces $variables with their values, expands wildcards such as *.txt and splits the line into words at every space.
Usually that is what you want. Sometimes it is not. Quotes tell the shell to treat part of the line differently.
Spaces split words
mkdir my photos
This does not create one folder named "my photos". The space splits the line into two arguments, so it creates two folders, my and photos. To keep the text together, use quotes:
mkdir "my photos"
This creates one folder with a space in its name.
Single quotes
Text inside single quotes is completely literal. The shell changes nothing inside.
name="Alex"
echo 'Hello, $name'
This prints Hello, $name. The $name is not replaced.
Double quotes
Text inside double quotes is kept together as one word, but $variables and $(commands) are still replaced.
echo "Hello, $name"
echo "Today is $(date +%A)"
The first prints Hello, Alex. A good rule for beginners: use double quotes around variables almost always, and single quotes when you want the exact text.
Why you should quote variables
file="my notes.txt"
cat $file
cat "$file"
Without quotes, the shell splits the value at the space and cat receives two arguments, my and notes.txt, which fails. With quotes, cat receives one argument. Forgetting quotes around variables is one of the most common causes of strange bugs in shell scripts.
Escaping with a backslash
A backslash \ removes the special meaning of the character after it.
echo "She said \"hi\""
echo "Price: \$5"
echo hello\ world
- The first prints
She said "hi". - The second prints
Price: $5instead of treating$5as a variable. - The third escapes the space, so
hello worldis one word.
Characters with special meaning include $, ", \, *, ?, &, ; and spaces.
Command substitution
Command substitution runs a command and puts its output into another command. Write the command inside $( ).
today=$(date +%F)
echo "Backup for $today"
count=$(ls | wc -l)
echo "There are $count items here"
mkdir "backup-$(date +%F)"
The shell runs the part inside the brackets first and replaces it with the output. date +%F prints the date as 2026-10-05, so the last command creates a folder named backup-2026-10-05.
There is an older form that uses backticks. It works, but $( ) is the preferred modern form because it is easier to read and can be nested.
Special variables
The shell sets some variables for you. Scripts use them often, and you will see them again in the scripting lessons.
echo $?
echo $$
echo $#
echo $@
echo $0
$?is the exit status of the last command.0means success. Any other number means something went wrong.$$is the process ID of the current shell.$#is the number of arguments given to a script.$@is all of those arguments.$0is the name of the script.
"$var" is almost never wrong, while a bare $var breaks as soon as the value contains a space.