Bash: The `read` Command
The read command is used to read a single line from standard input and assign its words to one or more variables. It is one of the most common commands used for handling user input and processing file content in a while loop.
Basic Usage
echo "Hello World" | while read var1 var2; do
echo "var1: $var1"
echo "var2: $var2"
done
# Result:
# var1: Hello
# var2: World
By default, read uses the characters in the IFS variable (space, tab, newline) to split the input line into words and assigns them sequentially to the variables provided.
The `-p` (prompt) Option
The -p option allows you to display a prompt message to the user before reading the input. This is a crucial feature for creating interactive scripts.
read -p "What is your name? " name
echo "Hello, $name!"
# A sample interaction:
# What is your name? John
# Hello, John!
This is the most common and user-friendly way to get input from a user in a Bash script.
The `-r` (raw) Option
The -r option prevents read from interpreting backslash escapes. It is highly recommended to always use -r to avoid unexpected behavior.
# Without -r, \t is interpreted as a tab character
echo "This is a line with a tab: \t" | while read line; do
echo "Output: '$line'"
done
# Result (tab is removed):
# Output: 'This is a line with a tab: '
# With -r, \t is treated as a literal string
echo "This is a line with a tab: \t" | while read -r line; do
echo "Output: '$line'"
done
# Result:
# Output: 'This is a line with a tab: \t'
The `-d` (delimiter) Option
The -d option allows you to specify a single character as the delimiter for the entire input. The read command will stop reading when it encounters this delimiter instead of a newline.
echo "alpha:beta:gamma" | while read -r -d: word; do
echo "Word: $word"
done
# Result:
# Word: alpha
# Word: beta
# Word: gamma
The `-d` option is especially useful for processing data that is not separated by newlines, such as comma-separated values (CSV) on a single line.
The Relationship between `-d`, `IFS`, and Word Splitting
Understanding the interaction between these is crucial for advanced scripting.
# The `read` command trims characters from the beginning and end of the read string if they are in the IFS variable.
# The -d option only changes the end-of-input delimiter.
# This example uses a pipeline to show the behavior clearly.
IFS=' '
echo " First Second, Third Fourth ," | while read -r -d, word; do
echo "=$word="
done
# Result:
# = First Second=
# = Third Fourth=
In this case, read -d, reads each segment until a comma is found. Since the default IFS includes spaces, read trims leading and trailing spaces from each segment. However, it does not split words in the middle of a segment; for example, "First Second" is not broken into two words. The comma is not part of the `IFS` so it is not trimmed.
Reading a File Line by Line
The most common use case for read is to process a file line by line within a while loop. This is the most efficient and reliable method.
while read -r line; do
echo "Processing line: $line"
done < file.txt
By default, read uses the newline character as its delimiter, making it perfect for this task. The -r option is used to ensure any backslashes in the file are treated literally.