• 九、处理用户输入


    读取参数

    位置参数变量是标准的数字

    $0是脚本名

    $1是第一个参数

    $2是第二个参数

    ...

    每个参数都是用空格分隔,如果参数值有空格需要使用引号(单双引号都行)

    如果要获取第10个参数及其以上需要加上花括号如${10}

    [root@tzPC 14Unit]# bash test4.sh 1 2 3 4 5 6 7 8 9 10 11 
    The tenth parameter is 10
    The total is 110
    [root@tzPC 14Unit]# cat test4.sh 
    #!/bin/bash
    echo The tenth parameter is ${10}
    total=$[ ${10} * ${11} ]
    echo The total is $total

    读取脚本名

    使用$0,这里需要注意,$0获取的脚本名有时候是全路径的,我们只要脚本名的话需要使用basename命令。

    [root@tzPC 14Unit]# bash /root/script/14Unit/test5.sh
    
    The script name is : test5.sh
    [root@tzPC 14Unit]# cat test5.sh
    #!/bin/bash
    #Using basename with the $0 parameter
    name=$(basename $0)
    echo 
    echo The script name is : $name

    注意,在使用位置参数时需要判断脚本是否有参数传递,没有则会报错

    [root@tzPC 14Unit]# cat test7.sh
    #!/bin/bash
    #testing parameters before use
    if [ -n "$1" ]
    then
            echo Hello $1
    else
            echo "Sorry"
    fi

    参数统计

    $#统计命令行参数个数

    可以配合if-then语句中的-ne测试命令行参数数量,参数数量不对给予提示。

    取命令行最后一个参数是${!#}而非${$#},因为在花括号内不能使用$

    [root@tzPC 14Unit]# cat test8.sh
    #!/bin/bash
    #Grabbing the last parameter
    params=$#
    echo The last parameter is $params
    echo The last parameter is ${!#}

    当命令行没有参数时,$#值为0,${!#}变量会返回命令行的脚本名

    抓取所有数据

    $*将命令行所有参数当作一个单词保存,视为一个整体

    $@将命令行所有参数当作一个字符串,多个独立单词,可以使用遍历

    移动变量

    shift命令

    默认会将每个参数向左移动一个位置。

    变量$3移到$2,$2移到$1,$1的值会被删除,$0值不变还是脚本名

    可用于不知道多少个参数的遍历。

    [root@tzPC 14Unit]# cat test9.sh 
    #!/bin/bash
    #demonstrating the shift command
    count=1
    while [ -n "$1" ];do
            echo "Parameter $count = $1"
            count=$[ $count +1 ]
            shift
    done

    可以一次性移动多个位置,shift n

    [root@tzPC 14Unit]# bash test10.sh 1 2 3 4 5
    The original parameters: 1 2 3 4 5
    Here's the new first parameter:3
    [root@tzPC 14Unit]# cat test10.sh 
    #!/bin/bash
    #demonstrating a multi-position shift
    echo "The original parameters: $*"
    shift 2
    echo "Here's the new first parameter:$1"

     处理选项跟参数

    使用getopt命令

    命令格式

    getopt optstring parameters

    getopt命令可以接受一系列任意形式的命令行选项和参数,并将它们转成适当的格式。

    在getopt命令后的optstring中写出要在脚本中用到的选项跟参数,在每个需要参数的选项后加一个冒号。

    [root@tzPC 14Unit]# getopt ab:cd -a -b test1 -cd test2 test3
     -a -b test1 -c -d -- test2 test3

    在linux中,双破折号表示选项列表结束,后面都是参数

    在如上例子中,b后面冒号表示跟参数test1,选项有-a -b -c -d其中-d后面都是参数。

    parameters中指定了一个不在optstring中的选项会报错,可以使用-q忽略错误信息

    [root@tzPC 14Unit]# getopt ab:cd -a -b test1 -cde test2 test3
    getopt:无效选项 -- e
     -a -b test1 -c -d -- test2 test3
    [root@tzPC 14Unit]# getopt -q ab:cd -a -b test1 -cde test2 test3
     -a -b 'test1' -c -d -- 'test2' 'test3'

     在脚本中使用getopt

    使用set命令的--选项能把原本命令行的选项跟参数值传给getopt命令处理,getopt命令处理后会把结果替换原来的命令行选项和参数。(书里写的太绕口了,同时还有一处错误,没有写-d会出现一条错误信息

    写法如下

    set -- $(getopt -q ab:cd "$@")

    要求:a、b、c、d是脚本的选项,其中b选项有个参数,判断脚本输入的选项跟参数

    [root@tzPC 14Unit]# bash test18.sh -ab test -c -d bbb aaa
    -a option
    -b option,with parameter value 'test'
    -c option
    -d option
    parameter #1: 'bbb'
    parameter #2: 'aaa'

     脚本如下

    [root@tzPC 14Unit]# cat test18.sh
    #!/bin/bash
    #Extact command line options & values with getopt
    set -- $(getopt -q ab:cd "$@")
    while [ -n "$1" ]
    do      
            case "$1" in
            -a)echo "-a option";;
            -b)param="$2" 
    #esac后面的shift每次循环都将参数左移,所以现在$2时b选项后的参数,后面的shift将把b选项的参数左移。
            echo "-b option,with parameter value $param"
            shift;;
            -c)echo "-c option";;
            -d)echo "-d option";;
            --) shift
             break ;;
    #遇到--说明后面都是参数,跳出循环
            *)echo "$1 is not an option";;
            esac
            shift
    done
    
    #输出参数
    count=1
    for param in "$@"
    do
            echo "parameter #$count: $param"
            count=$[ $count + 1 ]
    done

     getopt命令会把空格当成参数分隔符,而不是根据双引号把带有空格的参数当作一个整体。

    [root@tzPC 14Unit]# bash test18.sh -ab aaa -cd "bbb ccc" ddd
    -a option
    -b option,with parameter value 'aaa'
    -c option
    -d option
    parameter #1: 'bbb
    parameter #2: ccc'
    parameter #3: 'ddd'

     这种情况得使用getopts命令

    getopts命令

    1. 是bash自带命令
    2. 处理完所有参数后会退出并返回一个大于0的退出码
    3. 与getopts不同的是,去掉错误消息需要在optstring之前加一个冒号
    4. 会用到两个环境变量,OPTARG会保存选项跟的参数值,OPTIND保存了参数列表中正在处理的参数位置
    5. 参数值可以包含空格
    6. 解析命令行选项时会移除开头的-,所以case下的选项没有-
    7. 会将命令行中未定义的选项都统一输出为问号

    效果如下

    [root@tzPC 14Unit]# bash test19.sh -a -b "abc cba" -d
    -a option
    -b option,with value abc cba
    Unknown option: ?

    脚本如下

    [root@tzPC 14Unit]# cat test19.sh
    #!/bin/bash
    #simple demonstration of the getopts command
    while getopts :ab:c opt
    do
            case "$opt" in
             a) echo "-a option";;
             b) echo "-b option,with value $OPTARG";;
             c) echo "-c option";;
             *) echo "Unknown option: $opt";;
            esac
    done

     测试$OPTIND变量

    代码如下

    [root@tzPC 14Unit]# cat test19.sh
    #!/bin/bash
    #simple demonstration of the getopts command
    while getopts :a:b:cd: opt
    do
            case "$opt" in
             a) echo "-a option,with value $OPTARG $OPTIND" ;;
             b) echo "-b option $OPTIND,with value $OPTARG  $OPTIND";;
             c) echo "-c option" $OPTIND;;
             d) echo "-d option " $OPTIND,with value $OPTARG $OPTIND;;
             *) echo "Unknown option: $OPTIND";;
            esac
    done
    shift $[ $OPTIND - 1 ]
    echo
    count=1
    for param in "$@"
    do
            echo "Parameter $count: $param"
            count=$[ $count + 1 ]
    done

     结果

    [root@tzPC 14Unit]# bash test19.sh -b bbb -a aaa -c -d ddd
    -b option 3,with value bbb  3
    -a option,with value aaa 5
    -c option 6
    -d option  8,with value ddd 8

     $OPTIND变量计算方式为test19.sh位置为1,-b为2,bbb参数为3,-a为4,aaa参数为5,-c为6,-d为7,ddd参数为8

    获取用户输入

    可以一次读取多个变量的值,值与值之间使用空格分割,read命令后面没有指定变量名则会赋值给特定环境变量REPLY 

    [root@tzPC ~]# read a b
    hello world
    [root@tzPC ~]# echo $a
    hello
    [root@tzPC ~]# echo $b
    world
    [root@tzPC ~]# echo $a $b
    hello world

     read常见用法及参数

     -s 隐藏你输入的信息

    [root@tzPC ~]# read -s passwd

    -p 提示信息

    [root@tzPC ~]# read -p "input your passwd:" -s passwd

     也可以使用echo -n,-n的意思是不换行

    [root@tzPC ~]# echo -n "please input:" ; read pass

     -t 限制输入时间,单位秒

    如果定时器过期,read命令会以非零退出状态码退出

    [root@tzPC 14Unit]# bash test25.sh
    Please enter your name: 
    Sorry, too Slow!
    [root@tzPC 14Unit]# cat test25.sh
    #!/bin/bash
    #timing the data entry
    if read -t 5 -p "Please enter your name: " name
    then 
            echo "Hello $name,welcome to my script"
    else 
            echo
            echo "Sorry, too Slow!"
    fi

     -n 输入长度限制

    [root@tzPC 14Unit]# bash test26.sh
    Do you want to continue [Y|N]? y
    fine, continue on...
    [root@tzPC 14Unit]# cat test26.sh
    #!/bin/bash
    #getting just one character of input
    read -n1 -p "Do you want to continue [Y|N]? " anser
    case $anser in
            Y | y )echo 
                   echo "fine, continue on...";;
            N | n )echo
                   echo "OK,goodbye"
                    exit;;
    esac

     -r 可以输入空格,等特殊字符

    [root@tzPC ~]# read -r line
    !@#!@#  !@# 123 
    

     从文件中读取

    调用read命令读取文件,每次会从文件中读取一行文本,读完后返回非零状态码。

    [root@tzPC 14Unit]# bash test28.sh
    Line 1: 123
    Line 2: 321
    Line 3: 1234567
    [root@tzPC 14Unit]# cat test28.sh
    #!/bin/bash
    #reading data from a file 
    count=1
    cat test | while read line
    do
            echo "Line $count: $line"
            count=$[ $count + 1 ]
    done

    练习

    vim test_read.sh
    [root@tzPC ~]# cat test_read.sh
    #!/bin/bash
    
    read -p "请输入姓名:" NAME
    read -p "请输入年龄:" AGE
    read -p "请输入性别:" SEX
    
    cat<<eof
    *****************************
    你的基本信息如下:
    姓名:$NAME
    年龄:$AGE
    性别:$SEX
    ******************************
    eof

     学习来自:《Linux命令行与Shell脚本大全 第3版》第14章

    今天的学习是为了以后的工作更加的轻松!
  • 相关阅读:
    Pytorch安装
    使用Inception-v3进行图像分类
    Tensorflow模型保存与载入
    LSTM用于MNIST手写数字图片分类
    卷积神经网络应用于MNIST数据集分类
    手工设计神经MNIST使分类精度达到98%以上
    关于优化器的选择
    手动设计神经网络进行MNIST分类
    Matplotlib学习
    Apiview使用方法
  • 原文地址:https://www.cnblogs.com/tz90/p/13321242.html
Copyright © 2020-2023  润新知