read命令是bash内置命令,可从标准输入或者文件描述符中读取一行并将该行按空格拆分为多个字符串赋值给多个变量。

第一个字符串赋值给第一个变量,第二个字符串赋值给第二个变量,依此类推。如果没有为read命令提供变量名称,将整行赋值给REPLY变量。

在本教程中,我们将说明如何在Linux使用read命令读取用户的输入并保存到多个变量中。

read 命令

read命令语法形式是read [options] [name...]。为了简单说明read命令的工作方式,请按快捷键CTRL+ALT+T打开终端,运行命令read var1 var2

read命令将会等待用户输入。可以输入任意两个字符串并使用空格进行分隔,例如输入Hello World。输入完成后按Enter。

你将会发现read命令将Hello字符串分配给变量var1World字符串赋值给变量var2。我们可以运行命令echoprintf验证打印变量验证这一点。

read var1 var2
echo $var1
ehco $var1
Hello
World

如果没有为read命令提供变量名称,则将整行分配给REPLY变量。你可以再次终端运行命令read

接着输入任意字符串,也可以继续输入Hello World来验证这一点。最后运行命令echo $REPLY打印$REPLY

read
echo $REPLY
Hello World

如果为read命令指定的变量名称大于用户输入并按空格拆分后字符串数量,其余变量名称将不会被赋值。

如果为read命令指定的变量名称小于用户输入并按空格拆分后字符串数量,其余字符串将赋值给最后一个变量名称。

例如命令echo "Hello" | (read var1 var2; echo -e "Var1: $var1 \nVar2: $var2")

当你运行命令echo $var1打印变量var1时,将会打印字符串Hello。命令echo $var2打印空的输出。

#小于
echo "Hello" | (read var1 var2; echo -e "Var1: $var1 \nVar2: $var2")

#大于
echo "www myfreax com" | (read var1 var2; echo -e "Var1: $var1 \nVar2: $var2")

read 命令分隔符

read命令默认使用一个或多个空格,制表符和换行符作为分隔符,拆分字符串为多个字符串,然后分配给多个变量名称。

如果要使用其它分隔符拆分字符串,请将要作为分隔符的字符赋值给IFS变量。例如命令IFS=":"IFS变量设置为:

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

如果用户输入字符串连续包含多个IFS变量指定的分隔符号。read命令将会在两个彼此相邻的分隔符,生成空值分配给变量。

例如IFS变量指定的分隔符号是:,而用户输入的是Linux::is:awesome.。read命令将会在::之间生成一个空值分配给变量。

echo "Linux::is:awesome." | \
  (IFS=":" read -r var1 var2 var3 var4; echo -e "Var1: $var1 \nVar2: $var2 \nVar3: $var3 \nVar4: $var4")
Var1: Linux 
Var2:  
Var3: is 
Var4: awesome.

read命令还允许您使用多个分隔符号来拆分字符串。当指定多个分隔符号时,请将分隔符分配给IFS变量,并且在它们之间没有空格。

例如命令IFS="-_"使用_-作为分隔符,

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

read 命令组合echo与管道

您可以使用其他方法将标准输入传递给read命令,例如管道,here-string或heredoc。而不是在标准输入的默认方式键盘。

例如命令echo "Hello, World!" | (read var1 var2; echo -e "$var1 \n$var2")。这里之所以使用括号括起readecho命令。

是因为管道的右则是在Shell的子进程运行的,如果没有括号命令echo -e "$var1 \n$var2"并不是和read命令同一进程运行。就会导致两个变量输出都是空。

echo "Hello, World!" | (read var1 var2; echo -e "$var1 \n$var2")
Hello,
World!

read 命令组合HereDoc

默认情况下,read命令将反斜杠解释为转义符,有时可能会导致意外行为。要禁用反斜杠转义,请使用read命令的-r选项。

在使用read命令时,您应该始终与read命令的-r选项一起使用。你可以运行命令read <<< "Hello, \tWorld!"与命令read -r <<< "Hello, \tWorld!"

验证在使用read-r选项和没有-r选项时的区别。

read <<< "Hello, \tWorld!"
read -r <<< "Hello, \tWorld!"
Hello, tWorld!
Hello, \tWorld!

read 命令提示消息

当编写交互式Shell脚本时,可以使用read命令获取用户输入。您还可以使用read命令的-p选项,打印一条提示消息告知用户当前输入在做什么操作。

如果Shell脚本要求用户输入敏感信息,例如密码,可以使用read命令-s选项隐藏用户的输入。

例如命令read -r -s -p "Enter your password: "询问用户的密码并隐藏在终端的输出。

read -r -p "Are you sure?"
read -r -s -p "Enter your password: "

通常,您可以在while循环内使用read命令来强制用户提供预期的答案之一。shutdown.sh脚本将提示用户重启系统。

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
shutdown.sh

read 命令数组字符串

要将read命令拆分后的字符串分配给数组,而不是变量名称,请使用read命令的-a选项。

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

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

结论

read命令用于将读取用户输入行拆分为单词。如果您有任何问题或反馈,请随时发表评论。