Linux shell编程之处理用户输入

目录

处理用户输入

①命令行参数

读取参数

测试参数

②特殊变量——记录命令行参数

获取位置参数的个数:$#

命令行最后一个参数: ${!#}

抓取参数

③移动变量

④处理选项

处理简单选项

分离参数和选项

⑤获得用户输入——read命令

基本的读取

超时

隐藏方式读取

从文件中读取

 


 

前言

>>>目前为止,我们涉及到的知识包括如何编写脚本,处理数据、变量和文件

>>>bash shell提供了不同方法来从用户获取数据,包括命令行参数,命令行选项,以及从键盘读取输入等

 


 

①命令行参数

读取参数

>>>bash shell会将一些称为位置参数(positional parameter)的特殊变量分配给输入到命令行中的所有参数

>>>当需要输入多个命令行参数,需要在命令行上每个参数用空格隔开

案例

[bei@localhost test]$ cat parameter.sh
#!/bin/bash
echo "file_name=$0"
echo "parameter1=$1"
echo "parameter2=$2"
[bei@localhost test]$ bash parameter.sh para_1 para_2
file_name=parameter.sh
parameter1=para_1
parameter2=para_2

说明

>>>位置参数变量是标准的数字,$0是程序名parameter.sh,$1是第一个参数para_1,$2是第二个参数para_2

>>>变量在第9个之后变量最好用大括号括起来 ${10}

>>>如果参数含有空格,则需要将参数用引号引起来,否则会当做两个变量使用

 

测试参数

>>>在shell脚本使用命令行参数时,如果脚本没有加参数可能会出问题,为了避免此情况,
     在使用参数前,可以先用test命令测试参数是否存在

案例

[bei@localhost test]$ cat parameter.sh
#!/bin/bash
if [ -z "$1" ]                #使用test命令"-z"测试$1字符串是否为0
then
        echo "usage:bash $0 para_1"    #$1字符串为0的话的话,提示用户该以什么格式输入,并退出
        exit
else
        echo "Great,parameter1=$1"
fi
[bei@localhost test]$ bash parameter.sh
usage:bash parameter.sh para_1
[bei@localhost test]$ bash parameter.sh hello
Great,parameter1=hello

 


 

②特殊变量——记录命令行参数

获取位置参数的个数:使用特殊变量$#

     可以在脚本任何地方使用这个变量,即用法用普通变量

案例

[bei@localhost test]$ cat parameter.sh
#!/bin/bash
echo "count of parameter : $# "
[bei@localhost test]$ bash parameter.sh
count of parameter : 0
[bei@localhost test]$ bash parameter.sh 1 2 3
count of parameter : 3

案例:在使用参数前测试参数的总数,并测试参数是否为空

[bei@localhost test]$ cat parameter.sh
#!/bin/bash
if [ $# -ne 2 ]
then
        echo "Usage:bash $0 parameter1 parameter2"
else
        if [ -z $1 ] || [ -z $2 ]
        then
                echo "error:check the parameter"
        else
                echo "Graet parameter1=$1,parameter2=$2"
        fi
fi
[bei@localhost test]$ bash parameter.sh
Usage:bash parameter.sh parameter1 parameter2
[bei@localhost test]$ bash parameter.sh hello ""
error:check the parameter
[bei@localhost test]$ bash parameter.sh hello world
Graet parameter1=hello,parameter2=world

命令行最后一个参数: ${!#}

[bei@localhost test]$ cat parameter.sh
#!/bin/bash
echo "the last parameter is ${!#}"
[bei@localhost test]$ bash parameter.sh 1 2 3
the last parameter is 3

 

 

抓取参数

>>>需求:将命令行参数全部抓取下来,然后再去遍历

>>>思路:bash shell提供了连个变量$*$@区队所有参数快速访问

说明:

>>>$*是将命令行上提供的所有参数当做单个单词保存,即将所有参数当做一个整体的变量

>>>$@是将命令上提供的所有参数当做一个个独立的参数,即当做一个列表,会单独处理每个参数

案例

[bei@localhost test]$ cat parameter.sh
#!/bin/bash
#testing $* and $@
echo "Using the \$* method: $*"
echo "Using the \$@ method: $@"
[bei@localhost test]$ bash parameter.sh hello world
Using the $* method: hello world
Using the $@ method: hello world

         从表面上看,两个变量产生的输出是一样的,都显示了所有命令行参数

         下面的案例给出二者的差异

案例

[bei@localhost test]$ cat parameter.sh
#!/bin/bash
count=1
for i in "$*"
do
        echo "\$* parameter #$count : $i"
        count=$[ $count + 1 ]
done
count=1
for j in "$@"
do
        echo "\$@ parameter $count : $j"
        count=$[ $count + 1 ]
done
[bei@localhost test]$ bash parameter.sh hello world
$* parameter 1 : hello world
$@ parameter 1 : hello
$@ parameter 2 : world

注意:$@$*最好用引号引起来,否则输出会有差异

 


 

③移动变量

>>>bash shell提供了shift命令来操作命令行参数根据它们的相对位置来移动命令行参数

>>>此方法在你不知道有多少参数是个不错的选择,你可以只操作第一个参数,移动参数,然后继续操作第一个参数

案例

[bei@localhost test]$ cat shift.sh
#!/bin/bash
count=1
while [ -n "$1" ]
do
        echo "parameter $count: $1"
        count=$[ $count + 1 ]
        shift
done
[bei@localhost test]$ bash shift.sh a b c d
parameter 1: a
parameter 2: b
parameter 3: c
parameter 4: d

>>> shift默认步长为1,参数左移1位,若为shift 2,步长为2

案例

[bei@localhost test]$ cat shift.sh
#!/bin/bash
count=1
while [ -n "$1" ]
do
        echo "parameter $count: $1"
        count=$[ $count + 1 ]
        shift 2
done
[bei@localhost test]$ bash shift.sh 1 2 3 4 5 6 7 8
parameter 1: 1
parameter 2: 3
parameter 3: 5
parameter 4: 7

注意:执行此脚本不能传入奇数个命令行参数,否则会造成死循环

>>>使用shift命令的时候要小心,如果参数被移除了,这些值就会被丢弃了,无法再恢复

[bei@localhost test]$ cat shift.sh
#!/bin/bash
count=1
while [ -n "$1" ]
do
        echo "parameter $count: $1"
        count=$[$count+1]
        shift
done
echo""
echo "$*"
[bei@localhost test]$ bash shift.sh  a b c d
parameter 1: a
parameter 2: b
parameter 3: c
parameter 4: d

说明:当我执行完shift命令后,再去echo命令行参数,输出为空,即原来的参数被丢弃了

 


 

④处理选项

>>>bash命令后面的选项是在单破折号后的字母,他能改变命令的行为

>>>处理简单选项可以使用while循环和case语句

 

处理简单选项

案例

[bei@localhost test]$ cat option.sh
#!/bin/bash
while [ -n "$1" ]
do
        case "$1" in
                -a) echo "Found the option -a";;
                -b) echo "Found the option -b";;
                -c) echo "Found the option -c";;
                *) echo "$1 is not an option";;
        esac
        shift
done
[bei@localhost test]$ bash option.sh -a -b -c -d
Found the option -a
Found the option -b
Found the option -c
-d is not an option

 

分离参数和选项

>>>在执行脚本的时候,同时用到选项和参数的情况下,如何将二者分开

>>>使用特殊字符双破折号(--)即shell会用双破折号表明选项列表结束,
        在双破折号之后,脚本就可以将剩下的命令行参数当参数处理

案例

[bei@localhost test]$ cat option.sh
#!/bin/bash
while [ -n "$1" ]
do
        case "$1" in
                -a) echo "Found the option -a";;
                -b) echo "Found the option -b";;
                -c) echo "Found the option -c";;
                --) shift
                        break;;
                *) echo "$1 is not an option"
        esac
        shift
done
count=1
for i in "$@"
do
        echo "parameter $count = $i"
        count=$[ $count + 1 ]
done
[bei@localhost test]$ bash option.sh -a -b -c -- hello world
Found the option -a
Found the option -b
Found the option -c
parameter 1 = hello
parameter 2 = world

说明:break命令之前的shift命令,是用来移除双破折号,避免出现在参数中

 


 

⑤获得用户输入——read命令

>>>当需要在脚本运行时,实现人与脚本的交互,即为实时获得用户的输入,
         比如写一个用来获得用户实时输入的密码的脚本
         bash shell提供了一个命令:read命令,解决了我们的需求

 

基本的读取

>>>read命令从标准输入(键盘)或另一个文件描述符中接受输入,在收到输入后,raad命令会将数据放进一个变量

案例:

[bei@localhost test]$ cat read.sh
#!/bin/bash
echo -n "Please input your username:"
read username
echo "-----------"
echo "Welcome,$username!"
[bei@localhost test]$ bash read.sh
Please input your username:bei
-----------
Welcome,bei!

注意:倒数第三行的"bei"是我自己在键盘上敲的,即标准输入,然后放进变量username,在脚本后面使用

         echo-n选项把文本字符串和命令输出显示在同一行,即该选项不会在字符串末尾输出换行符

案例:使用-p选项,直接在read命令行指定提示符

[bei@localhost test]$ cat read.sh
#!/bin/bash
read -p "Please input your username: " username
echo "-----------"
echo "Welcome,$username"
[bei@localhost test]$ bash read.sh
Please input your username: bei
-----------
Welcome,bei

 

超时

>>>脚本启动后,执行read命令时,若用户迟迟未输入,脚本会一直苦等着

>>>如果想让用户是否有输入,脚本都会继续往下执行,可以使用-t选项来制定一个定时器

>>>当计时器到期后,read命令会返回一个非零退出状态码

案例

[bei@localhost test]$ cat read.sh
#!/bin/bash
if read -t 5 -p "Please input your username: " username
then
        echo "Welcome,$username"
else
        echo "Sorry,you are too late to input your username."
fi
[bei@localhost test]$ bash read.sh
Please input your username: Sorry,you are too late to input your username.
[bei@localhost test]$ bash read.sh
Please input your username: bei
Welcome,bei

 

隐藏方式读取

>>>需求:当希望在屏幕输入的内容,不想被“显示”在屏幕上,比如在输入密码的时候

>>>方法:使用-s选项,该选项会避免将传给read命令的数据显示在显示器上

(实际上,数据会被显示,只是read命令会将文本颜色设成跟背景色一样)

案例

[bei@localhost test]$ cat read.sh
#!/bin/bash
read -t 5 -p "Please input your username: " username
read -t 5 -s -p "Please input your password: " password
echo ""
echo "Welcome,$username,your password is $password"
[bei@localhost test]$ bash read.sh
Please input your username: bei
Please input your password:
Welcome,bei,your password is hahahaha

 

从文件中读取

>>>使用read命令读取Linux系统上文件里保存的数据,每次调用read命令,都会从文件中读取一行文本

>>>当文件中再没有内容时,read命令会退出并返回非零退出状态码

>>>read命令从文件读取输入——cat $file | while read line

案例

[bei@localhost test]$ cat date
IP1 1.1.1.1
IP2 192.168.1.1
IP6 2.2.2.2
IP9 172.16.1.1
[bei@localhost test]$ cat read.sh
#!/bin/bash
count=1
read -p "Input the file you want to read:" file
cat $file | while read line
do
        echo "line $count : $line"
        count=$[ $count + 1 ]
done
echo "Finished processing the file $file"
[bei@localhost test]$ bash read.sh
Input the file you want to read:./date
line 1 : IP1 1.1.1.1
line 2 : IP2 192.168.1.1
line 3 : IP6 2.2.2.2
line 4 : IP9 172.16.1.1
Finished processing the file ./date

说明:

>>>cat命令的输出内容通过管道符传递作为read的输入内容

>>>当文件读取完最后一行,read命令返回一个非零状态码,while循环结束

 

 


 

说明:

>>>以上内容是本人学习的总结

>>>如还有错误,请留言,指正

>>>亦可分享自己的想法,互相学习

猜你喜欢

转载自blog.csdn.net/Mr_Bei/article/details/82830151