Bash read Command

The read built-in command reads a line from standard input (or a file descriptor) and splits it into words, assigning each word to a named variable. It is one of the most frequently used built-ins for writing interactive scripts and processing text input in Bash.
The general syntax of the read built-in takes the following form:
read [options] [name...]Reading Input into Variables
To see how the command works, open a terminal, type read var1 var2, and press Enter. The command waits for input. Type two words and press Enter again:
read var1 var2
Hello, World!The words are assigned to the variables passed to read as arguments. Use echo
or printf
to verify:
echo $var1
echo $var2Hello,
World!Instead of typing on the terminal, you can pass input to read using piping, here-string, or heredoc
:
echo "Hello, World!" | (read var1 var2; echo -e "$var1 \n$var2")read and echo are enclosed in parentheses and executed in the same subshell.Hello,
World!Here is an example using a here-string and printf:
read -r var1 var2 <<< "Hello, World!"
printf "var1: %s \nvar2: %s\n" "$var1" "$var2"var1: Hello,
var2: World!If no variable names are provided, the entire line is assigned to the REPLY variable:
echo "Hello, world!" | (read; echo "$REPLY")Hello, World!If the number of variables supplied to read is less than the number of words, the last variable receives all remaining input:
echo "Linux is awesome." | (read var1 var2; echo -e "Var1: $var1 \nVar2: $var2")Var1: Linux
Var2: is awesome.When more variables are provided than words, extra variables are set to empty:
echo "Hello, World!" | (read var1 var2 var3; echo -e "Var1: $var1 \nVar2: $var2 \nVar3: $var3")Var1: Hello,
Var2: World!
Var3:Backslash Escaping and the -r Option
By default, read interprets the backslash as an escape character, which can cause unexpected behavior. To disable backslash escaping, invoke the command with the -r option.
The example below shows how read works with and without -r:
read <<< "Hello, \tWorld!"
printf %s "$REPLY"Hello, tWorld!read -r <<< "Hello, \tWorld!"
printf %s "$REPLY"Hello, \tWorld!Always prefer read -r unless you specifically need escape processing.
Changing the Delimiter (IFS)
The default behavior of read is to split the line into words using spaces, tabs, and newlines as delimiters. To use a different character, assign it to the IFS variable (Internal Field Separator):
echo "Linux:is:awesome." | (IFS=":" read -r var1 var2 var3; echo -e "$var1 \n$var2 \n$var3")Linux
is
awesome.When IFS is set to a character other than space or tab, words are separated by exactly one occurrence of that character:
echo "Linux::is:awesome." | \
(IFS=":" read -r var1 var2 var3 var4; echo -e "Var1: $var1 \nVar2: $var2 \nVar3: $var3 \nVar4: $var4")The line is separated into four words. The second word is empty, representing the segment between the two consecutive : delimiters:
Var1: Linux
Var2:
Var3: is
Var4: awesome.You can specify multiple delimiters by assigning more than one character to IFS with no spaces between them:
echo 'Linux_is-awesome.' | (IFS="-_" read -r var1 var2 var3; echo -e "$var1 \n$var2 \n$var3")Linux
is
awesome.Prompting the User
When writing interactive Bash scripts, use the -p option to display a prompt before reading. The prompt is printed before read executes and does not include a newline:
read -r -p "Are you sure? "Generally, you would use read within a while
loop to prompt the user for one of the expected answers.
The following script prompts the user for a system reboot :
while true; do
read -r -p "Do you wish to reboot the system? (Y/N): " answer
case $answer in
[Yy]* ) reboot; break;;
[Nn]* ) exit;;
* ) echo "Please answer Y or N.";;
esac
doneTo read sensitive information such as a password, use the -s option to suppress terminal echoing:
read -r -s -p "Enter your password: "Reading a File Line by Line
One of the most common uses of read is processing a file line by line. The standard pattern is:
while IFS= read -r line; do
echo "$line"
done < filename.txtIFS=— clears the field separator for this command so that leading and trailing whitespace in each line is preserved.-r— disables backslash interpretation so that backslashes in the file are read literally.< filename.txt— redirects the file as standard input to the loop.
To process the output of a command instead of a file, use process substitution:
while IFS= read -r line; do
echo "Found: $line"
done < <(find /var/log -name "*.log")while read loop (command | while read). In Bash, the right side of a pipe runs in a subshell, so any variables set inside the loop will not be available after the loop ends. Use process substitution or input redirection instead.Assign the Words to an Array
To read words into an array
instead of individual variables, use the -a option:
read -r -a MY_ARR <<< "Linux is awesome."
for i in "${MY_ARR[@]}"; do
echo "$i"
doneLinux
is
awesome.When both an array and a variable name are given, all words are assigned to the array.
Reading a Fixed Number of Characters
The -n option tells read to return after reading exactly N characters instead of waiting for a newline:
read -r -n 1 -p "Press any key to continue..."This is useful for “press any key” prompts and single-character menu selections. The command returns as soon as the character is received without requiring the user to press Enter.
Custom Line Delimiter with -d
By default, read stops at a newline. The -d option changes the delimiter to any character:
read -r -d ":" var <<< "hello:world"
echo "$var"helloread consumed input up to and including the first : and assigned the preceding text to var. This is useful for parsing delimited streams or null-terminated input (-d '').
The Timeout Option
The -t option limits how long read waits for input, in seconds. Fractional values are supported (for example, 0.5 for half a second):
read -r -t 10 -p "Enter your nickname (10 seconds timeout): " nickname
if [[ $? -gt 128 ]]; then
echo "Timeout occurred!"
nickname="(default)"
else
echo "Hello, $nickname!"
fiIf a complete line arrives before the timeout, read succeeds. If it times out, it returns an exit status greater than 128 and discards any partial input.
When the timeout is set to 0, read checks whether input is immediately available and returns without waiting.
Quick Reference
| Option | Description |
|---|---|
read var | Read a line into var |
read var1 var2 | Split input into multiple variables |
read -r var | Disable backslash escaping (recommended) |
read -p "prompt" var | Display a prompt before reading |
read -s var | Silent mode — do not echo input |
read -t N var | Timeout after N seconds |
read -n N var | Read exactly N characters |
read -d ":" var | Read until delimiter character |
read -a arr | Read words into an array |
IFS=":" read -r a b | Split on a custom delimiter |
while IFS= read -r line | Read a file line by line |
For a printable quick reference, see the Bash cheatsheet .
Troubleshooting
Variables are empty after the while read loop
This happens when read runs in a subshell — most commonly when piping into the loop: command | while read. Variables set inside a subshell are not visible in the parent shell. Use process substitution or input redirection instead: while IFS= read -r line; do ...; done < <(command) or done < file.
Leading and trailing whitespace is stripped from input
By default, IFS includes space and tab, so read trims whitespace from the start and end of each word. To preserve whitespace, clear IFS before read: IFS= read -r line.
Backslash characters disappear
Without -r, read processes backslashes as escape characters (\n becomes a newline, \t becomes a tab, etc.). Always use read -r unless you specifically want this behavior.
-t option not working
The timeout option is a Bash-specific feature. If your script runs under sh (e.g., #!/bin/sh), -t may not be available. Use #!/bin/bash in the shebang line.
FAQ
Why is my variable empty after the while read loop?
The right side of a pipe runs in a subshell in Bash. Variables set inside the subshell are lost when it exits. Replace command | while IFS= read -r line with while IFS= read -r line; do ...; done < <(command) to keep variables in the current shell.
What does IFS= (empty assignment) do before read?
Setting IFS to an empty value before read disables field splitting entirely, which means leading and trailing whitespace is preserved and no splitting on spaces or tabs occurs. It is the recommended form when reading file lines: while IFS= read -r line.
Should I always use read -r?
Yes, in almost all cases. Without -r, backslashes in the input are interpreted as escape sequences, which can silently corrupt data. Use read -r by default and omit it only when you explicitly need escape processing.
How do I read input without showing it on the terminal?
Use the -s (silent) flag: read -r -s -p "Password: " pass. The input is captured in $pass without being echoed to the terminal. Remember to print a newline after (echo) since -s suppresses it.
What is the REPLY variable?
When read is called without any variable names, the entire input line is stored in the built-in variable REPLY. It is automatically available without being declared: read -r; echo "$REPLY".
Conclusion
The read command is the primary way to accept input in Bash scripts — whether prompting a user, processing a file line by line, or splitting delimited data. Use read -r by default, clear IFS when whitespace matters, and prefer input redirection over pipes to avoid subshell variable scoping issues.
Tags
Linuxize Weekly Newsletter
A quick weekly roundup of new tutorials, news, and tips.
About the authors

Dejan Panovski
Dejan Panovski is the founder of Linuxize, an RHCSA-certified Linux system administrator and DevOps engineer based in Skopje, Macedonia. Author of 800+ Linux tutorials with 20+ years of experience turning complex Linux tasks into clear, reliable guides.
View author page