shell编程 - 读取键盘输入

读取键盘输入

read —— 从标准输入读取输入值。

        内嵌命令read读取一行标准输入,该命令可用于读取键盘输入值应用重定向读取文件中的一行

        read命令的语法结构是:

read [-options] [variable...]

其中options是一条或者多条选项;variable则是一个到多个的用于存放输入量的变量。若没有提供任何的命令,shell默认变量REPLY来存储数据行

#!/bin/bash

echo -n "Please enter an integer -> "
read int

if [[ "$int" =~ ^-?[0-9]+$ ]];then
        if [ $int -eq 0 ];then
                echo "$int is zero"
        else
                if [ $int -lt 0 ];then
                        echo "$int is negative."
                else
                        echo "$int is positive."
                fi
                if [ $((int % 2)) -eq 0 ];then
                        echo "$int is even."
                else
                        echo "$int is odd."
                fi
        fi
else
        echo "Input value is not an integer." >&2
        exit 1
fi

在以下脚本中,read命令将输入值赋给多个变量

#!/bin/bash

# read-multiple:read multiple values from keyboard

echo -n "Enter one or more values > "
read var1 var2 var3 var4 var5

echo "var1 = '$var1'"
echo "var2 = '$var2'"
echo "var3 = '$var3'"
echo "var4 = '$var4'"
echo "var5 = '$var5'"

需要特别注意的是:

当输入少于或者多于5个值得时候,read的运作方式

若read命令读取的值少于预期的数目,则多余的变量值为空;若read命令读取的值多于预期的数目,则最后的变量包含了所有的多余值。

如果read命令之后没有变量,则会为所有的输入值分配一个shell变量:REPLY

有趣的选项

-p 选项来显示提示信息 (取代上面脚本中的echo -n打印语句,作用与之等效)

#!/bin/bash

# read-single:read multiple values into default variable

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

使用-s -t选项,可以以“秘密”的形式读取输入的参数,常常用于读取密码输入

#!/bin/bash
# read-secret: input a secret passphrase
if read -t 10 -sp "Enter secret passphrase > " secret_pass;then
        echo -e "\nSecret passphrase = '$secret_pass'"
else
        echo -e "\nInput timed out" >&2
        exit 1
fi

提示用户输入密码,系统的等待时间是10秒。若10秒内用户没有完成输入,脚本以出错状态结束运行。又因为用了-s选项,所以输入的密码不会显示到屏幕上。

使用IFS间隔输入字段

由shell变量IFS(Internal Field Separator)设定,默认值包含空格、换行符和制表符。

我们可以通过改变IFS值来控制read命令输入的间隔方式。

#!/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 "Pw = '$pw'"
        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

以上脚本知识点:

1、shell命令允许命令执行前对一到多个变量进行赋值,这种赋值方式会改变接下来所执行命令的操作环境。但是赋值的效果是暂时性的,只有在命令执行周期内有效。等效于

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

显然,对于相同的效果,将变量赋值语句置于执行命令前是更为简洁的方法。

2、操作符 “<<<”象征一条嵌入字符串。与嵌入文档类似,只不过更为简短,它包含的是一条字符串。

为什么不用

echo "$file_info" | IFS=":" read user pw uid gid name home shell

read不可重定向

验证输入

程序具备了读取键盘输入功能的同时,也带来了新的挑战——验证输入。

#!/bin/bash

# read-validate: validate input

invalid_input () {
        echo "Invalid input '$REPLY'" >&2
        exit 1
}

read -p "Enter a single item > "

# input is empty
[[ -z "$REPLY" ]] && invalid_input

# input is multiple items(invalid)
(( $(echo "$REPLY" | wc -w) > 1 )) && invalid_input

# is inpuot a valid filename?
if [[ "$REPLY" =~ ^[-[:alnum:]\._]+$ ]];then
        echo "'$REPLY' is a valid filename."
        if [[ -e $REPLY ]];then
                echo "And file '$REPLY' exists."
        else
                echo "However,file '$REPLY' does not exist."
        fi

        # is input a floating point number?
        if [[ $REPLY =~ ^-?[[:digit:]]*\.[[:digit:]+$] ]];then
                echo "'$REPLY' is a floating point number."
        else
                echo "'$REPLY' is not a floating point number."
        fi

        # is input an integer?
        if [[ $REPLY =~ ^-?[[:digit:]]+$ ]];then
                echo "'$REPLY' is an integer."
        else
                echo "'$REPLY' is not an integer."
        fi
else
        echo "The string '$REPLY' is not a valid filename."
fi

菜单驱动程序

菜单驱动是一种常见的交互方式。在菜单驱动的程序会呈现给用户一系列的选项,并请求用户进行选择。

#!/bin/bash

# read-menu:a menu driven system information program

clear
echo "
Please Select:

1.Display System Information
2.Display Disk Space
3.Display Home Space Utilization
0.Quit
"
read -p "Enter selection [0-3] > "

if [[ $REPLY =~ ^[0-3]$ ]];then
        if [[ $REPLY == 0 ]];then
                echo "Program terminated."
                exit
        fi
        if [[ $REPLY == 1 ]];then
                echo "Hostname: $HOSTNAME"
                uptime
                exit
        fi
        if [[ $REPLY == 2 ]];then
                df -h
                exit
        fi
        if [[ $REPLY == 3 ]];then
                if [[ $(id -u) == 0 ]];then
                        echo "Home Space Utilization(All Users)"
                        du -sh /home/*
                else
                        echo "Home Space Utilization($USER)"
                        du -sh $HOME
                fi
                exit
        fi
else
        echo "Invalid entry." >&2
        exit 1
fi

以上脚本主要有两部分。第一部分展示了菜单并获取用户的响应,第二部分对响应进行验证并执行相应的选项。


可以关注作者微信公众号,追踪更多有价值的内容!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值