# Asking Questions: read

read waits for the user to type a line and keeps it in a variable: -p shows a question first, -s hides what's typed, and ${name:-default} gives an answer that was left empty a default.

Apprentice · Unix · Linux · Updated November 10, 2026

## After this lesson you can

- Ask the user a question with read -p and keep the answer in a variable
- Hide a typed answer with read -s, and give an empty answer a default with ${name:-default}

## Key takeaways

- read name waits for a line of typing and keeps it in the variable name.
- read -p "Question? " name shows the question first, on the same line as the answer.
- read -s hides what's typed, for a password or a surprise. Add an echo after it, because the Enter doesn't show either.
- ${name:-Happy birthday} is name's value, or Happy birthday if it's empty: a default for anyone who presses Enter.
- Use -r on every read, so a backslash in the answer stays a backslash.

Arguments work well when you know what a script needs. Your cousin doesn't: she runs your card maker for the first time, it prints an unsigned card, and she has no idea it wanted a second word. Installers solve this by asking: "Install to which folder?", "Continue? [Y/n]". A script can ask too, wait for an answer and carry on with it. An IT tech's setup script asks for the new user's name; a backup script asks "Delete the old copies? [y/N]" before it does something it can't undo.

The examples use the card shop from *Arguments: $1, $# and "$@"*: `cd ~/terminal-practice/cards`.

## read: wait for an answer

`read` stops and waits for the user to type a line and press Enter, then keeps that line in a variable. Try it at the prompt:

```bash
read name
```

The prompt doesn't come back: bash is waiting. Type `Maya` and press Enter, then:

```bash
echo "Hello, $name"
```

```text
Hello, Maya
```

`read` reads from the keyboard, the **standard input** of *Three Streams: Output, Errors and Input*, so a pipe or a `<` can answer it too. That's how the exercise's check answers your script's questions without a person.

## -p: ask a question first

A blinking cursor with no question is a puzzle. `-p` (for *prompt*) shows the question first, and the answer is typed on the same line. Make `ask-card.sh`:

```bash
#!/usr/bin/env bash
# ask-card.sh: asks who the card is for, then makes it.
read -r -p "Who is the card for? " name
echo "Happy birthday, $name!"
```

End the question with a space, so the answer doesn't touch it. Run it, and type `Diego` when it asks:

```bash
chmod +x ask-card.sh
./ask-card.sh
```

```text
Who is the card for? Diego
Happy birthday, Diego!
```

The `-r` keeps a backslash in the answer as a backslash instead of a special character. It's never wrong to add, and ShellCheck (*Writing Scripts in VS Code*) asks for it on every `read`, so every example here uses it. On a Mac, these lines work in a script, which runs in bash 5; typed at zsh's own prompt, `read -p` means something else.

## -s: hide what's typed

Some answers shouldn't appear on the screen: a password, or a surprise when the birthday girl is sitting next to you. `-s` (for *silent*) hides the typing. Make `secret-card.sh`:

```bash
#!/usr/bin/env bash
# secret-card.sh: a card with a surprise inside, typed where no one can see it.
read -r -p "Who is the card for? " name
read -r -s -p "The surprise (hidden as you type): " surprise
echo
echo "Dear $name, $surprise" > "card-for-$name.txt"
echo "Saved card-for-$name.txt. No peeking!"
```

Run it, answer `Maya`, then type `You are getting a puppy!` for the surprise:

```bash
chmod +x secret-card.sh
./secret-card.sh
cat card-for-Maya.txt
```

```text
Who is the card for? Maya
The surprise (hidden as you type):
Saved card-for-Maya.txt. No peeking!
Dear Maya, You are getting a puppy!
```

Nothing showed while you typed, not even the Enter at the end, so the lone `echo` after `read -s` moves to a new line. `sudo` hides your password the same way. The answer is hidden, not secret: the script can still print it or save it, as this one does.

## A default for an empty answer

Most people send birthday cards, so the card maker shouldn't make everyone type "Happy birthday". Installers show the usual answer in square brackets, and pressing Enter picks it. In bash, `${greeting:-Happy birthday}` (read "greeting, or Happy birthday if it's empty") gives you the variable's value, or the default when there isn't one. Make `greeting.sh`:

```bash
#!/usr/bin/env bash
# greeting.sh: asks for a greeting, and offers one if you press Enter.
read -r -p "Who is the card for? " name
read -r -p "Greeting [Happy birthday]: " greeting
greeting=${greeting:-Happy birthday}
echo "$greeting, $name!"
```

Run it twice. The first time, answer `Diego` and press Enter at the greeting; the second, answer `Aunt Rosa` and `Thank you`:

```bash
chmod +x greeting.sh
./greeting.sh
./greeting.sh
```

```text
Who is the card for? Diego
Greeting [Happy birthday]:
Happy birthday, Diego!
Who is the card for? Aunt Rosa
Greeting [Happy birthday]: Thank you
Thank you, Aunt Rosa!
```

The same works for arguments: `${2:-Sam}` is the second argument, or Sam when there isn't one. Arguments suit a script that other scripts or a schedule run, with no one there to answer; questions suit a person at the keyboard. Many tools take an argument when it's given and ask when it isn't.

## Check yourself

2 questions to try on the lesson page.

## So what

`read -r -p` turns a script into a conversation: it asks, waits and carries on with the answer, hides what should stay hidden with `-s`, and offers a sensible default to anyone who presses Enter.

## Key terms

- [read](https://www.ask-codey.com/glossary/read-unix)
- [Shell Variable](https://www.ask-codey.com/glossary/shell-variable)
- [Standard Streams](https://www.ask-codey.com/glossary/standard-streams)

## Cheat sheets

- [Asking Questions: read](https://www.ask-codey.com/cheat-sheets/bash-reading-input-cheat-sheet)

## Related

- [Arguments: $1, $# and "$@"](https://www.ask-codey.com/lessons/bash-script-arguments)
- [Variables in the Shell](https://www.ask-codey.com/lessons/bash-shell-variables)
- [Quotes: Double, Single and None](https://www.ask-codey.com/lessons/bash-quoting)

Source: https://www.ask-codey.com/lessons/bash-reading-input
