Variables in the Shell

A shell variable is a name the shell keeps a value under, so owl_folder=… stores a long path once and $owl_folder hands it back in any command until you close the window.

Apprentice · Unix · Linux · Updated

After this lesson you can

  • Make a shell variable with name=value, with no spaces around the = and quotes around a value with spaces
  • Use a variable's value with $name, and tell what double quotes, single quotes and braces do to it

Key takeaways

  • name=value makes a shell variable. There are no spaces around the =, or bash reads the name as a command.
  • $name, read "the value of name", puts the value into a command, as in cd "$owl_folder" or echo "$owl_folder".
  • A value with spaces needs quotes, as in reminder="wind daily".
  • Double quotes fill in $name. Single quotes keep $name exactly as typed. ${name} marks where a name ends.
  • A variable lasts until you close the terminal window, and a name that was never set is empty, not an error.

Your class folder is ~/school/2026-fall/biology/lab-reports, and you type that whole path ten times a day. One slip of a letter and cd says there's no such folder. People who work in a terminal all day don't retype long things: they give them a short name once, and the shell remembers. That short name is a variable, and every script you'll write in this course is built on them. A web developer keeps a project's folder in one; an IT administrator keeps a server's address in one.

Set up the workshop

This chapter's practice folder is a workshop. Ada Wren, an inventor, keeps her machines there, and her newest project, a clockwork owl, sits in a folder four levels down. Copy these lines into your terminal. They make the folders and files, and they're safe to run again whenever you want a fresh copy:

mkdir -p ~/terminal-practice/workshop/tools ~/terminal-practice/workshop/projects/clockwork-owl/drawings && cd ~/terminal-practice/workshop
printf '#!/usr/bin/env bash\n# KETTLE-BOT 3000, by Ada Wren. Needs POWER set to on.\nif [ "$POWER" = "on" ]; then echo "Pouring tea..."; else echo "NO POWER"; fi\n' > kettle-bot
printf '#!/usr/bin/env bash\necho "Glug, glug. The gears are oiled."\n' > tools/oilcan
printf 'Dear diary: the owl hooted at 3 a.m. again.\n' > diary.txt
printf 'Wings: 12 brass feathers each\n' > projects/clockwork-owl/drawings/wings.txt
printf 'Hoots once an hour, on the hour\n' > projects/clockwork-owl/notes.txt
pwd
/home/sam/terminal-practice/workshop

kettle-bot and tools/oilcan are two tiny programs, the workshop's machines. The next lessons run them.

name=value: a label on a jar

Think of a jar on a shelf with a label on it. The label is the name, and what's inside is the value. Write the name, an = and the value, and the shell fills the jar:

owl_folder=~/terminal-practice/workshop/projects/clockwork-owl
echo $owl_folder
/home/sam/terminal-practice/workshop/projects/clockwork-owl

The first line printed nothing: the shell quietly kept the value. In the second, $owl_folder is read "the value of owl_folder". The $ tells the shell to open the jar and put what's inside into the command, and echo prints whatever it's given. The shell turned the ~ into your full home folder when it stored the value.

Now use it anywhere a path goes:

ls $owl_folder
cd $owl_folder/drawings
pwd
drawings  notes.txt
/home/sam/terminal-practice/workshop/projects/clockwork-owl/drawings

A variable like this, which only your shell knows about, is a shell variable. Its name can have letters, digits and underscores, can't start with a digit, and capital letters count: $Owl_folder is a different jar. Go back to the workshop with cd ~/terminal-practice/workshop.

No spaces around the =

In most writing you'd put spaces around an =. In the shell, that changes what the line means:

owl_folder = ~/terminal-practice/workshop/projects/clockwork-owl
owl_folder: command not found

With spaces, bash reads the line like any other command: the first word is the command to run, and there's no program called owl_folder. (Ubuntu sometimes adds suggestions of programs with a similar name, and a Mac words the message differently. The fix is the same.)

Spaces inside the value cause the same trouble, because a space ends the value:

reminder=wind daily
daily: command not found

Quotes keep the value in one piece. This is quoting: quotes tell the shell where a piece of text starts and ends.

reminder="wind daily"
echo $reminder
wind daily

Double quotes, single quotes and braces

The two kinds of quotes treat a $ differently. Double quotes fill in the value; single quotes keep everything exactly as typed:

echo "The owl lives in $owl_folder"
echo 'The owl lives in $owl_folder'
The owl lives in /home/sam/terminal-practice/workshop/projects/clockwork-owl
The owl lives in $owl_folder

When letters come right after a name, the shell can't tell where the name ends. Curly braces, ${part}, mark the end:

part=feather
echo "12 $parts"
echo "12 ${part}s"
12
12 feathers

The first line asked for a variable called parts, which was never set. The shell gave no error: a name that was never set is empty. That makes a misspelled name a quiet mistake, so if a command does something odd, echo the variable and look.

A good habit from here on: put a variable in double quotes when you use it, as in cd "$owl_folder". If its value ever has a space in it, like the photos to print folder in Moving Around: cd, .. and ~, the quotes keep it one argument.

How long a variable lasts

A shell variable lives in the window you made it in. Close the window, open a new one, and $owl_folder is empty again. Startup Files: .bashrc, .zshrc and source, in the next chapter, shows how to make one that's there every time. The shell also keeps some variables of its own, with names in capitals:

echo $HOME
/home/sam

On a Mac, everything in this lesson works the same in zsh. $HOME is /Users/sam there.

Check yourself

2 questions to try on the lesson page.

So what

Name a long path or a sentence once, and $name hands it back in any command. Scripts are made of exactly this: values with names.

Key terms

Cheat sheets

Related