D20

在Bash下可以采用内部命令read接收用户来自键盘的输入,并将输入的内容赋值给一个变量。

 

1. 基本的读取

语法:read [-p prompt] [variable1 variable2...]

-p选项用于在尝试读取任何输入之前显示prompt(提示信息)的内容到标准错误输出。一般使用这个选项提示用户输入哪些内容。

read命令每次从标准输入(或使用-u选项指定的文件描述符)中读取一行的内容,将第一个单词赋值给第一个变量variable1,第二个单词赋值给variable2,依次类推。如果输入的单词数少于指定的变量数,剩下的变量值设为空,环境变量IFS中的字符被作为分隔符来将输入的内容分隔为单词。

$ cat readUserInput_1.sh 
#!/bin/bash
#202006

read -p "Enter your name: " username #提示输入用户名,并将输入内容赋值给变量

read -p "Enter your email address: " email

read -p "Are you sure to continue? [y/n]" input

case $input in 
[yY]*)
        echo "Name: $username"
        echo "Email: $email"
        ;;
[nY]*)
        exit
        ;;
*)
        echo "Enter y or n, please."
        exit
        ;;
esac


#执行
$ ./readUserInput_1.sh 
Enter your name: Jessica
Enter your email address: a@b.com
Are you sure to continue? [y/n]y
Name: Jessica
Email: a@b.com

 

2. 输入超时

read命令的-t选项设置读取用户输入的超时时间。指定秒数内没有读入一整行的输入(即没有输入回车),read命令将超时并返回一个失败。

$ cat readUserInput_1.sh 
#!/bin/bash
#202006

read -t 5 -p "Enter your name: " username #添加-t选项,超时未输入返回状态码142

read -t 5 -p "Enter your email address: " email

read -t 5 -p "Are you sure to continue? [y/n]" input

case $input in 
[yY]*)
        echo "Name: $username"
        echo "Email: $email"
        ;;
[nY]*)
        exit
        ;;
*)
        echo "Enter y or n, please."
        exit
        ;;

 

3. 隐藏方式读取

read命令的-s选项来隐藏用户的输入。指定-s选项,则来自终端的输入不会被显示出来。当脚本验证密码时是很有用的。

$ cat readPassword.sh 
#!/bin/bash
#202006

password=''

echo -n "Enter password: " 

while IFS= read -r -s -n1 char #使用-n隐式的从标准输入每次读取一个字符,且反斜杠不做转义字符处理,并将读取的字符赋值给char
do
        if [ -z $char ] #如果char为空(即直接输出的回车),则退出while循环
        then 
                echo 
                break
        fi

        if [[ $char == $'\x08' || $char == $'\x7f' ]] #如果输入的是退格键或删除键
        then
                [[ -n $paassword ]] && password=${password:0:${#password}-1} #从password中移除最后一个字符
                printf '\b \b'  #向左删除一个*
        else #不是退格或删除键
                password+=$char #将变量char追加到password
                printf '*' #打印一个*
        fi
done

echo "Password is: $password"

执行脚本:

$ ./readPassword.sh 
Enter password: ***
Password is: abc

 

4. 从文件中读取

使用read命令从文件中读取数据的方法主要有两种:

1)在while或until循环中使用read命令,通过文件描述符一行一行的读取文件内容,后续介绍;

2)在for循环中使用cat <filename>来读取文件内容。

语法:

for data in $(cat filename)
do
    command1
    command2
    ...
    commandN
done

注意:这里的data不是逐行,而是根据环境变量IFS的值作为分隔符来逐个单词的读取文件内容。可以通过修改IFS来实现按行读取。

$ cat readFromFilebyfor.sh 
#!/bin/bash
#20200601

old_IFS=$IFS #保存原来的IFS

if [ $# -ne 1 ]
then
        echo "Usage: `basename $0` filename"
        exit
fi

if [ ! -f $1 ]
then
        echo "The file $1 does not exist!"
        exit 1
fi

IFS=$'\n' #改为按行分隔


for line in $(cat $1) #逐行读取文件
do
        echo $line
done

IFS=$old_IFS #恢复IFS

执行结果:

$ ./readFromFilebyfor.sh list.txt
ab dde
ab   dde
abde
333
a

补充:如果按照默认的IFS,则:

$ cat readFromFilebyfor.sh 
#!/bin/bash
#202006

if [ $# -ne 1 ]
then
        echo "Usage: `basename $0` filename"
        exit
fi

if [ ! -f $1 ]
then
        echo "The file $1 does not exist!"
        exit 1
fi

for line in $(cat $1) #按照默认的IFS分隔读取单词
do
        echo $line
done

执行结果:

$ ./readFromFilebyfor.sh list.txt
ab
dde
ab
dde
abde
333
a

注意:按照for循环结合IFS变量可以保留每行原有的格式,而while循环读取文件虽然方便,但会去掉重复的空格和制表符,即会消除每行的原有格式。请按需选择。

 

本节结束

 

欢迎大家评论交流,发现博文中存在的问题一定要留言哦