# 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 November 10, 2026

## 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:

```bash
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
```

```text
/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:

```bash
owl_folder=~/terminal-practice/workshop/projects/clockwork-owl
echo $owl_folder
```

```text
/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:

```bash
ls $owl_folder
cd $owl_folder/drawings
pwd
```

```text
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:

```bash
owl_folder = ~/terminal-practice/workshop/projects/clockwork-owl
```

```text
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:

```bash
reminder=wind daily
```

```text
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.

```bash
reminder="wind daily"
echo $reminder
```

```text
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:

```bash
echo "The owl lives in $owl_folder"
echo 'The owl lives in $owl_folder'
```

```text
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:

```bash
part=feather
echo "12 $parts"
echo "12 ${part}s"
```

```text
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:

```bash
echo $HOME
```

```text
/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

- [Shell Variable](https://www.ask-codey.com/glossary/shell-variable)
- [echo](https://www.ask-codey.com/glossary/echo)
- [Quoting](https://www.ask-codey.com/glossary/quoting)

## Cheat sheets

- [Variables in the Shell](https://www.ask-codey.com/cheat-sheets/bash-shell-variables-cheat-sheet)

## Related

- [Environment Variables: export and env](https://www.ask-codey.com/lessons/bash-environment-variables)
- [Moving Around: cd, .. and ~](https://www.ask-codey.com/lessons/bash-moving-around)

Source: https://www.ask-codey.com/lessons/bash-shell-variables
