read Command: Interactive Input in Shell Scripts
"I want my script to pause and let the user type in a name or password." When you hit that moment, the read command is the answer. In this article, Lina and Linny-senpai walk through how to capture keyboard input and read files with read, step by step.
What You'll Learn
- What the
readcommand does and why it matters - How to use prompts (
-p), hidden input (-s), and timeouts (-t) - The classic
while readpattern for processing a file line by line - Two beginner pitfalls: the "pipe trap" and why you should add
-r
1. What Is the read Command?
Conclusion: read is a builtin that reads one line from standard input into a variable, making your script interactive.
read command is for. read takes one line typed on the keyboard and stores it in a variable.What read does
read is a shell builtin that reads one line from standard input (such as the keyboard) and stores it in a variable. Use it whenever you want the user to enter something and then use that value inside your script.
ls or cat?ls and cat are commands that exist as executable files, like /bin/ls. But read is a feature built into the shell itself. That is why which read often finds nothing. Try type read instead and you will see read is a shell builtin.2. The Most Basic Usage
Conclusion: Type read variable and the shell waits; the line you enter before pressing Enter goes into that variable.
read name
Lina here and press Enter...?name. Let's check what's inside.read name Lina echo "Hello, $name"
Hello, Lina
Add $ to read a variable's value
The value you stored with read name is retrieved by adding a leading $, as in $name. Wrapping it in double quotes like echo "$name" is the safe style: it handles values that contain spaces correctly.
3. Showing a Prompt (-p)
Conclusion: read -p "message" variable prints a prompt before the input so the user knows what to type.
-p option to show a prompt message along with the input.read -p "Enter your name: " name echo "Welcome, $name"
Enter your name: Lina Welcome, Lina
-p is printed as-is. Ending it with a space like : makes the input position easier to read, so I recommend it.4. Reading Several Values at Once
Conclusion: List multiple variable names after read and space-separated input is distributed into each one.
read. If the input is also space-separated, each value goes to the matching variable.read -p "First and last name: " first last echo "First: $first / Last: $last"
First and last name: Lina Yamada First: Lina / Last: Yamada
Extra input goes into the last variable
With read a b (two variables) but input 1 2 3 4, a gets 1 and b gets all the rest (2 3 4). If there is too little input, the leftover variables stay empty.
5. Hiding Password Input (-s)
Conclusion: read -s does not echo the typed characters, so use it for passwords and other secrets.
-s (silent) option comes in. The characters you type are not shown on screen. Use it when reading passwords or secret values.read -s -p "Password: " pass
echo
echo "Characters entered: ${#pass}"Password: Characters entered: 8
-s only hides the display; the value is safely stored in the variable. Because -s also suppresses the newline when you press Enter, adding one echo right after keeps the output tidy. ${#pass} is the syntax for the length of a variable.6. Adding a Time Limit (-t)
Conclusion: read -t seconds makes read give up automatically if no input arrives within the given time.
-t (timeout). It waits the given number of seconds and moves on if there is no input.if read -t 5 -p "Type within 5 seconds: " answer; then
echo "You entered: $answer"
else
echo
echo "Time's up"
fiYou can test whether read succeeded with if
read returns "success" when it reads a line, and "failure" on a timeout or end of input (more on that below). Catching this with if read ...; then lets you branch based on whether input arrived.
7. Reading a File Line by Line (while read)
Conclusion: while read line; do ... done < file pulls a file into a variable one line at a time for processing.
while read combination is the best fit. This is a classic shell-scripting pattern, so memorize the whole shape and you will use it forever.while read line; do
echo "Read line: $line"
done < list.txt< list.txt part?list.txt into read." Each time read reads a line, it stores it in line and loops until there are no more lines. When it reaches the end of the file, read returns "failure," so the loop ends naturally.A safer form: while IFS= read -r line
In practice you will often see while IFS= read -r line; do ... done < file. The IFS= part prevents leading and trailing whitespace from being stripped, and -r reads backslashes (\) literally. The next section explains why.
8. Two Pitfalls Beginners Hit
Conclusion: A piped while read runs in a separate process so its variables vanish, and without -r backslashes disappear.
while read, but a counter I increment inside the loop is back to 0 after the loop... is it a bug?Pitfall 1: Variables Inside a Pipe Don't Survive
count=0
cat list.txt | while read line; do
count=$((count + 1))
done
echo "$count" # prints 0cat ... | while ..., the while part runs in a separate process (a subshell). Incrementing count there only changes a "clone." The original count is never updated.Fix: use a redirect instead of a pipe
count=0
while read line; do
count=$((count + 1))
done < list.txt
echo "$count" # counts correctlyWith the < list.txt redirect, while runs in the same process, so the change to count survives.
Pitfall 2: Without -r, Backslashes Disappear
-r — why do we add it?-r, read treats the backslash (\) as special and removes it. For example, reading the path C:\Users gives you C:Users. So when you want to read the input exactly as typed, adding -r is the rule.# Without -r: the backslashes are gone echo 'C:\Users\lina' | read path; echo "$path" # -> C:Userslina # With -r: read literally echo 'C:\Users\lina' | read -r path; echo "$path" # -> C:\Users\lina
When in doubt, add -r
Unless you have a specific reason not to, adding -r to read is the safe choice. Shell script linters (such as ShellCheck) also warn about a read without -r.
9. A Quick Exercise to Review
Exercise: write a greeting script (click for a solution)
Task: Ask "What's your name?", then use the entered name to print "Hello, NAME!"
Sample solution:
#!/bin/bash
read -p "What's your name? " name
echo "Hello, ${name}!"It shows a prompt with -p and prints the captured value with $name. Wrapping it as ${name} with braces makes the variable boundary clear and safe.
read -p, then display it with $name.read is a short command, but once you have -p, -s, -t, and while read, you can handle almost any "capture input" situation. From here, just keep using it in real scripts to build fluency.