zoukankan      html  css  js  c++  java
  • 【shell】shell编程(五)-读取参数

      通过前几篇文章的学习,我们学会了shell的基本语法。在linux的实际操作中,我们经常看到命令会有很多参数,例如:ls -al 等等,那么这个参数是怎么处理的呢? 接下来我们就来看看shell脚本对于用户输入参数的处理。

    命令行参数处理

    根据参数位置获取参数

      bash shell可根据参数位置获取参数。通过 $1 到 $9 获取第1到第9个的命令行参数。$0为shell名。如果参数超过9个,那么就只能通过${}来获取了, 例如获取第10个参数,那么可以写为${10}。

    示例一:

    #!/bin/bash
    #testinput.sh
    echo "file name: $0"
    echo "base file name: $(basename $0)"
    echo "param1: $1"
    echo "param2: ${2}"

    运行上面的的shell

    ./testinput.sh 12 34

    最终得到的结果如下:

    file name: ./testinput4.sh

    base file name: testinput4.sh

    param1: 12

    param2: 34

    成功的得到文件名和命令行输入的参数(命令行参数以空格分隔,如果参数包含了空格,那么久必须添加引号了)

    $0默认会获取到当前shell文件的名称,但是,它也包含(./),如果你以完整路径运行,那么这还会包含目录名。因此,上面通过basename命令来获取单纯的文件名$(basename $0)

    试想一下,假如我们写的shell的这个参数很多,那如果像上面那样一个一个去获取参数,那岂不是要写疯!下面就来看看如何解决这种情况。

    另外,还有几个特殊字符用来处理参数:

    参数处理说明
    $# 传递到脚本的参数个数
    $* 以一个单字符串显示所有向脚本传递的参数。
    如"$*"用「"」括起来的情况、以"$1 $2 … $n"的形式输出所有参数。
    $$ 脚本运行的当前进程ID号
    $! 后台运行的最后一个进程的ID号
    $@ 与$*相同,但是使用时加引号,并在引号中返回每个参数。
    如"$@"用「"」括起来的情况、以"$1" "$2" … "$n" 的形式输出所有参数。
    $- 显示Shell使用的当前选项,与set命令功能相同。
    $? 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。

      上面重要的是$#和$?,$#可以获取参数的格式,$?可用于判断一个命令执行的状态。

    例如下面一个批量删除用户的脚本就是根据$?获取上一个命令的执行状态码,然后判断是否正确执行命令:

    #!/bin/bash
    #delete user batch
    echo "please input username word to delete"
    read word
    #get All users like word*
    users=`/usr/bin/grep ${word} /etc/passwd | awk -F: -v word1=${word} 'index($1,wo
    rd1)>0 {print $1}'`
    if [ "${users}" = '' ]
     then
            echo "user is does not exist!"
            exit 1
    fi
    for username in ${users}
    do
            /usr/sbin/userdel -rf ${username} > /dev/null 2>/dev/null
    done
    if [ "0" = "$?" ]
            then
            echo "delete ok!"
    else
            echo "delete failed!"
    fi

    读取所有参数

    方法一

    既然bash shell通过位置可获取参数,那意味着如果我们知道参数的总个数就可以通过循环依次获取参数。那么如何获取参数总个数呢?

    在bash shell中通过 $# 可获取参数总数。

    示例:(循环获取参数)

    #!/bin/bash
    for (( index=0; index <= $#; index++ ))
    do
        echo ${!index}
    done

      以上示例,我们通过 $# 获取总参数个数。然后通过循环获取每个位置的参数。注意: 按照正常的理解,上面的 ${!index} 应该是 ${$index}才对, 对吧? 但是,由于${}内不能再写$符号,bash shell在这个地方是用了!符号,所以以上才写为了${!index}。

    方法二

    在bash shell中还可以通过 $* 和 $@ 来获取所有参数。但是这两者之间有着很大的区别:

    $* 会将命令行上提供的所有参数当作一个单词保存, 我们得到的值也就相当于是个字符串整体。

    $@ 会将命令行上提供的所有参数当作同一字符串中的多个独立的单词。

    可能文字看起来描述的不太清楚,那么还是通过示例来看二者的区别吧:

    #!/bin/bash
    #testinput.sh
    var1=$*
    var2=$@
    echo "var1: $var1"
    echo "var2: $var2"
    countvar1=1
    countvar2=1
    for param in "$*"
    do
        echo "first loop param$countvar1: $param"
        countvar1=$[ $countvar1 + 1 ]
    done
    echo "countvar1: $countvar1"
    
    for param in "$@"
    do
        echo "second param$countvar2: $param"
        countvar2=$[ $countvar2 + 1 ]
    done
    echo "countvar2: $countvar2"
     

    执行上面的示例:

    ./testinput.sh 12 34 56 78  

    上面示例的输出结果为:

    var1: 12 34 56 78

    var2: 12 34 56 78

    param1: 12 34 56 78

    countvar1: 2

    param1: 12

    param2: 34

    param3: 56

    param4: 78

    countvar2: 5

      通过上面的结果可见,直接输出看起来二者结果一样,但是通过for循环就可看出二者的区别了。上一篇文章我们讲到for循环会通过IFS定义的值进行分割,因此默认情况下,如果我们上面在for循环处不加引号,那么根据IFS中所定义的空格分割,最终也会导致看不出二者区别。

    获得用户输入

    单个输入

    有时候,我们在shell执行过程中获取用户的输入,以此与用户进行交互。这是通过read命令来实现的。下面就来看看其用法:

    示例一:

    #!/bin/bash
    echo -n "yes or no(y/n)?"
    read choice
    echo "your choice: $choice"

      运行以上示例,首先会输出”yes or no(y/n)?“, 然后会等待用户输入(-n参数表示不换行,因此会在本行等待用户输入),当用户输入后,会把用户输入的值赋值给choice变量, 然后最终输出 “your choice: (你输入的内容)”。

    事实上,我们可以不指定read后面的变量名,如果我们不指定, read命令会将它收到的任何数据都放进特殊环境变量REPLY中。如下:

    示例二:

    #!/bin/bash
    echo -n "yes or no(y/n)?"
    read
    echo "your choice: $REPLY"

    以上示例与示例一是等价的。

    有时候,我们需要用户输入多个参数,当然,shell是支持一次接受多个参数输入的。

    多个输入

    示例三:

    #!/bin/bash
    read -p "what's your name?" first last
    echo first: $first
    echo last: $last

      以上示例首先输出“what's your name?”, 然后在本行等待用户输入(此处用read -p实现以上示例的echo -n + read命令的不换行效果),输入的参数以空格分隔,shell会把输入的值依次赋值给first和last两个变量。如果输入的值过多,假如我输入了3个值,那么shell会把剩下的值都赋值给最后一个变量(即第二三两个的值都会赋值给last变量)。

    细想一下,有个问题,假如用户一直不输入,怎么办?一直等待?

    超时设置

    我们可以通过read -t 来指定超时时间(单位为秒),如果用户在指定时间内没输入,那么read命令就会返回一个非0的状态码。

    示例四:

    #/bin/bash
    if read -t 5 -p "Please enter your name: " name 
    then
        echo "Hello $name"
    else
        echo "Sorry, timeout! "
    fi

      运行以上示例,如果超过5秒没输入,那么就会执行else里面的。

    小结

      本篇简单的介绍了shell的输入参数以及接收用户输入。大家可以举一反三,结合之前所学的基础知识,可以写一些小的脚本应用了。

    接下来可以学习shell编程六:http://www.cnblogs.com/qlqwjy/p/8683972.html

  • 相关阅读:
    Python中的多线程编程
    Python中的变量以及变量的命名
    Python中的列表、元组、字典、字符串及切片操作
    Python中的socket编程
    Nginx对代理HTTP资源的限制访问
    【笨嘴拙舌WINDOWS】GDI映射方式
    【笨嘴拙舌WINDOWS】GDI(2)
    【笨嘴拙舌WINDOWS】GDI(1)
    【笨嘴拙舌WINDOWS】Dj,oh!nonono,It is about DC
    【笨嘴拙舌WINDOWS】消息机制
  • 原文地址:https://www.cnblogs.com/qlqwjy/p/7746009.html
Copyright © 2011-2022 走看看