Bash read Command

Published on

5 min read

Linux Bash read

Bash ships with a number of built-in commands that you can use on the command line or in your shell scripts.

In this article, we’ll explore the built-in read command.

Bash read Built-in

read is a bash built-in command that reads a line from the standard input (or from the file descriptor) and split the line into words. The first word is assigned to the first name, the second one to the second name, and so on.

The general syntax of the read built-in takes the following form:

read [options] [name...]

To illustrate how the command works, open your terminal, type read var1 var2, and hit “Enter”. The command will wait for the user to enter the input. Type two words and press “Enter”.

read var1 var2Hello, World!

The words are assigned to the names that are passed to the read command as arguments. Use echo or printf to verify it:

echo $var1echo $var2
Hello,
World!

Instead of typing on the terminal, you can pass the standard input to read using other methods such as 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! 

When no argument is provided to the read command, the entire line is assigned to the REPLY variable:

echo "Hello, world!" | (read; echo "$REPLY")
Hello, World!

If the number of arguments supplied to read is bigger than the number of words read from the input, the remaining words are assigned to the last name:

echo "Linux is awesome." | (read var1 var2; echo -e "Var1: $var1 \nVar2: $var2")
Var1: Linux 
Var2: is awesome.

Otherwise, if the number of arguments is less than the number of names, an empty value is assigned to the remaining names:

echo "Hello, World!" | (read var1 var2 var3; echo -e "Var1: $var1 \nVar2: $var2 \nVar3: $var3")
Var1: Hello, 
Var2: World! 
Var3: 

By default, read interprets the backslash as an escape character, which sometimes may cause unexpected behavior. To disable backslash escaping, invoke the command with the -r option.

Below is an example showing how read works when invoked with and without the -r option:

read <<< "Hello, \tWorld!"printf %s "$REPLY"
Hello, tWorld!
read -r <<< "Hello, \tWorld!"printf %s "$REPLY"
Hello, \tWorld!

Generally, you should always use read with the -r option.

Changing the Delimiter

The default behavior of read is to split the line into words using one or more spaces, tabs, and newline as delimiters. To use another character as a delimiter, 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, the words are separated by exactly one 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 in four words. The second word is an empty value representing the segment between the delimiters. It is created because we used two delimiter characters next to each other(::).

Var1: Linux 
Var2:  
Var3: is 
Var4: awesome.

You can use more than one delimiter to split the line. When specifying multiple delimiters, assign the characters to the IFS variable without a space between them.

Here is an example using _ an - as delimiters:

echo 'Linux_is-awesome.' | (IFS="-_" read -r var1 var2 var3; echo -e "$var1 \n$var2 \n$var3")
Linux 
is 
awesome.

Prompt String

When writing interactive bash scripts, you can use the read command to get the user input.

To specify a prompt string, use the -p option. The prompt is printed before the read is executed and doesn’t include a newline.

Here is a simple example:

read -r -p "Are you sure?"

Generally, you would use the read command inside a while loop to force the user to give one of the expected answers.

The code below will prompt the user for 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
done

If the shell script asks users to enter sensitive information, like password, use the -s option that tells read not to print the input on the terminal:

read -r -s -p "Enter your password: "

Assign the Words to Array

To assign the words to an array instead of variable names, invoke the read command with the -a option:

read -r -a MY_ARR <<< "Linux is awesome."

for i in "${MY_ARR[@]}"; do 
  echo "$i"
done
Linux 
is 
awesome.

When both an array and a variable name are given, all words are assigned to the array.

Conclusion

The read command is used to split a line of input into words.

If you have any questions or feedback, feel free to leave a comment.