Skip to content
DevOps devops shell 5 min read

Reading User Input

Most scripts run on their own, but sometimes you need to ask the person running the script a question first. Maybe you need a username, a password, or a simple “are you sure?” before deleting something. The Bash built-in command read (a command baked into the shell that pauses and waits for someone to type) is how you collect that input. This page shows you how to read values, show prompts, hide passwords, set sensible defaults, and build a safe confirmation step before a destructive action.

What read does

read pauses your script, waits for the user to type a line and press Enter, and stores what they typed into a variable. By default it reads one line.

#!/usr/bin/env bash
echo "What is your name?"
read name
echo "Hello, $name!"

Run it:

chmod +x greet.sh
./greet.sh

Output:

What is your name?
Ada
Hello, Ada!

The word name after read is the variable name. After the user presses Enter, $name holds their answer. If you do not give read a variable name, Bash stores the line in a default variable called $REPLY.

Tip: Always quote your variables when you use them, like "$name". If the user types nothing or types text with spaces, quoting keeps your script from breaking.

Showing a prompt with read -p

Using a separate echo line for the question works, but read has a cleaner way. The -p flag (short for “prompt”) prints a message on the same line and then waits, with the cursor sitting right after your text.

#!/usr/bin/env bash
read -p "Enter the server hostname: " hostname
echo "You entered: $hostname"

Output:

Enter the server hostname: web-01
You entered: web-01

This reads better and keeps the cursor next to the question, which is the standard look for command-line tools.

When to use this: any time you ask a single short question. Use -p instead of a separate echo so the prompt and the input stay on one line.

Hiding passwords with read -s

When you ask for a password or any secret, you do not want it showing on screen where someone could read it over your shoulder, and you do not want it saved in your terminal scrollback. The -s flag (short for “silent”) hides what the user types.

#!/usr/bin/env bash
read -s -p "Enter your database password: " db_password
echo    # print a newline because -s swallows the Enter key's line break
echo "Password received (${#db_password} characters)."

Output:

Enter your database password: 
Password received (16 characters).

Notice the lone echo after the silent read. Because -s hides everything including the Enter key, the cursor stays on the prompt line. A bare echo prints a blank line so your next message starts cleanly. The ${#db_password} part counts how many characters were typed without ever printing the password itself.

Security warning: Never put a password directly inside your script file, and avoid passing secrets on the command line (they show up in ps and shell history). Reading them at runtime with read -s keeps them out of files and process listings. For automation that cannot type, use a secrets manager or an environment variable loaded from a protected file (chmod 600).

Providing default values

Often a question has an obvious answer, and you want to let the user just press Enter to accept it. Bash gives you a clean pattern using parameter expansion: read into a variable, then fall back to a default if it is empty.

#!/usr/bin/env bash
read -p "Which port should the app use? [8080]: " port
port="${port:-8080}"
echo "Using port $port"

Output (user pressed Enter):

Which port should the app use? [8080]: 
Using port 8080

The expression ${port:-8080} means “use $port, but if it is empty or unset, use 8080 instead.” Showing the default in square brackets in the prompt, like [8080], is a common convention so the user knows what they will get if they do nothing.

Useful read options

OptionWhat it doesWhen to use it
-p "text"Shows a prompt on the same lineAlmost every interactive question
-sHides typed characters (silent)Passwords, API keys, secrets
-rTreats backslashes literally (no escaping)Reading file paths or any raw text — use it by default
-t NTimes out after N secondsStop waiting forever in automated runs
-n NReturns after N characters (no Enter needed)Single-key answers like y/n
-a arrReads words into an arrayCollecting a list on one line

Tip: Get into the habit of writing read -r everywhere. Without -r, Bash treats a backslash as an escape character, which mangles Windows paths and other text. The -r flag almost never hurts.

A safe confirmation prompt before a destructive action

The most important use of read in DevOps work is asking “are you sure?” before something dangerous, like deleting files or dropping a database. Here is a complete, safe pattern that defaults to “no” so an accidental Enter never destroys anything.

#!/usr/bin/env bash
set -euo pipefail

target="/var/log/myapp"

read -r -p "Delete all logs in $target? This cannot be undone. [y/N]: " answer

case "${answer,,}" in
  y|yes)
    sudo rm -rf "${target:?}"/*
    echo "Logs deleted."
    ;;
  *)
    echo "Cancelled. Nothing was deleted."
    exit 0
    ;;
esac

Output (user typed n or just pressed Enter):

Delete all logs in /var/log/myapp? This cannot be undone. [y/N]: n
Cancelled. Nothing was deleted.

A few things make this safe and worth copying:

  • The prompt shows [y/N] with a capital N, signalling that “no” is the default.
  • ${answer,,} lowercases the input, so Y, YES, and y all match.
  • The case statement only deletes when the user clearly says yes; anything else cancels.
  • ${target:?} aborts with an error if target is somehow empty, which prevents the catastrophic rm -rf /*.
  • set -euo pipefail at the top makes the script stop on the first error.

When to use this: before any command that deletes, overwrites, restarts a production service, or changes infrastructure. When not to: in fully automated scripts that run from cron or CI, where no human is present to answer. For those, take the choice as a command-line flag instead and skip the prompt.

Best practices

  • Use read -r by default so backslashes in input are not silently eaten.
  • Always show prompts with -p and include the default value in [brackets].
  • Read secrets with -s and never store passwords in the script file.
  • Default destructive confirmations to “no” ([y/N]) so a stray Enter is harmless.
  • Validate input after reading it — check for empty strings or wrong formats before using the value.
  • Quote every variable ("$var") to handle spaces and empty answers safely.
  • For non-interactive automation, accept values as arguments or environment variables instead of prompting.
Last updated June 15, 2026
Was this helpful?