read command

Usage

Sometimes, the script needs to provide part of the data by the user during the execution process, then you can use the read command. It stores the user's input into a variable to facilitate the use of the code behind. When the user presses the Enter key, the input is complete.

The format of the read command is as follows.

read [-options] [variable...]

In the above syntax, options is a parameter option, and variable is one or more variable names used to store the input value. If no variable name is provided, the environment variable REPLY will contain the entire line of data entered by the user.

The following is an example demo.sh.

#!/bin/bash

echo -n "Enter some text>"
read text
echo "your input: $text"

In the above example, a line of prompt text is displayed first, and then it will wait for the user to enter the text. The text entered by the user is stored in the variable text and displayed on the next line.

$ bash demo.sh
Enter some text> hello, world
Your input: hello, world

read can accept multiple values ​​entered by the user.

#!/bin/bash
echo Please, enter your firstname and lastname
read FN LN
echo "Hi! $LN, $FN !"

In the above example, read assigns values ​​to two variables at the same time based on the user's input.

If the user's input is less than the number of variables given by the read command, the extra variable value is empty. If the user has more input items than the defined variables, the extra input items will be included in the last variable.

If the variable name is not defined after the read command, the environment variable REPLY will contain all the input.

#!/bin/bash
# read-single: read multiple values ​​into default variable
echo -n "Enter one or more values> "
read
echo "REPLY ='$REPLY'"

The running result of the above script is as follows.

$ read-single
Enter one or more values> abcd
REPLY ='abcd'

In addition to reading keyboard input, the read command can be used to read files.

#!/bin/bash

filename='/etc/hosts'

while read myline
do
  echo "$myline"
done <$filename

The above example uses the read command to read the contents of a file. The directional character < after the done command directs the content of the file to the read command, reading one line at a time and storing it in the variable myline until the file is read.

Parameters

The parameters of the read command are as follows.

(1)-t parameter

The -t parameter of the read command sets the number of seconds for the timeout. If the specified time is exceeded and the user still has no input, the script will give up waiting and continue execution.

#!/bin/bash

echo -n "Enter some text>"
if read -t 3 response; then
  echo "User has entered"
else
  echo "User did not input"
fi

In the above example, the input command will wait for 3 seconds. If the user does not input for more than this time, the command will fail to execute. According to the return value of the command, if transfers to the else code block and continues execution.

The environment variable TMOUT can also play the same role, specifying the time (in seconds) that the read command waits for user input.

$ TMOUT=3
$ read response

The above example also waits for 3 seconds, and if the user has not entered, it will time out.

(2)-p parameter

The -p parameter specifies the prompt information entered by the user.

read -p "Enter one or more values> "
echo "REPLY ='$REPLY'"

In the above example, first display Enter one or more values ​​>, and then accept the user's input.

(3)-a parameter

The -a parameter assigns the user's input to an array, starting at position zero.

$ read -a people
alice duchess dodo
$ echo ${people[2]}
dodo

In the above example, user input is assigned to an array people, and the second member of this array is dodo.

(4)-n parameter

The -n parameter specifies that only a few characters should be read as the variable value, rather than the entire line.

$ read -n 3 letter
abcdefghij
$ echo $letter
abc

In the above example, the variable letter only contains 3 letters.

(5)-e parameter

The -e parameter allows the user to use the shortcut keys provided by the readline library when inputting, such as auto-completion. For specific shortcut keys, please refer to the chapter "Line Operations".

#!/bin/bash

echo Please input the path to the file:

read -e fileName

echo $fileName

In the above example, the read command accepts the file name entered by the user. At this time, the user may want to use the file name "auto-completion" function of the Tab key, but the input of the read command does not support the function of the readline library by default. The -e parameter allows users to use auto-completion.

(6) Other parameters

--d delimiter: Define the first character of the string delimiter as the end of user input instead of a newline character. --r: raw mode, which means that the backslash character entered by the user is not interpreted as an escape character. --s: Make the user's input not displayed on the screen, which is often used to enter passwords or confidential information. --u fd: Use file descriptor fd as input.

IFS variable

The values ​​read by the read command are separated by spaces by default. The separation flag can be modified by customizing the environment variable IFS (Internal Field Separator, abbreviation of Internal Field Separator).

The default value of IFS is space, tab symbol, newline symbol, usually the first one (ie space).

If you define IFS as a colon (:) or semicolon (;), you can separate the values ​​separated by these two symbols, which is very useful for reading files.

#!/bin/bash
# read-ifs: read fields from a file

FILE=/etc/passwd

read -p "Enter a username> "user_name
file_info="$(grep "^$user_name:" $FILE)"

if [-n "$file_info" ]; then
  IFS=":" read user pw uid gid name home shell <<< "$file_info"
  echo "User ='$user'"
  echo "UID ='$uid'"
  echo "GID ='$gid'"
  echo "Full Name ='$name'"
  echo "Home Dir. ='$home'"
  echo "Shell ='$shell'"
else
  echo "No such user'$user_name'" >&2
  exit 1
fi

In the above example, IFS is set to a colon, and then used to decompose a line of the /etc/passwd file. The assignment command of IFS and the read command are written on one line. In this case, the change of IFS only takes effect on the following commands. After the command is executed, IFS will automatically restore the original value. If it is not written on one line, use the following writing method.

OLD_IFS="$IFS"
IFS=":"
read user pw uid gid name home shell <<< "$file_info"
IFS="$OLD_IFS"

In addition, in the above example, <<< is the Here string, which is used to convert the variable value to standard input, because the read command can only parse standard input.

If IFS is set to an empty string, it is equivalent to reading the entire line into a variable.

#!/bin/bash
input="/path/to/txt/file"
while IFS = read -r line
do
  echo "$line"
done <"$input"

The above command can read the file line by line, each line is stored in the variable line, and the next line will be read after printing it out.