Shell编程中的用户输入处理(3):在shell脚本中,处理命令行参数

3. 在shell脚本中,处理命令行参数

3.1 检查输入参数

使用条件判断,检查输入参数个数

# !/bin/bash                # 指定shell类型

if [ $# -lt 2 ]             # $#获取输入个数,选项-lt表示less than
then
    echo "please input at least 2 param" 
fi

默认情况下,用户的输入是不可靠的,我们需要对用户输入进行检查,除此之外正则表达式也能对输入参数进行限定。

3.2 移动位置参数

使用shift命令移动参数变量,处理多个参数

# !/bin/bash               

result=0

while [ -n "$1" ]               # 通过循环,每次读取$1位置参数
do
    result=$[ $result + $1 ]    # $1位置参数与原参数和累加
    shift                       # 把$2位置参数向前移动到$1,原$1位置参数不可用
done

echo "sum of result is $result" 

执行脚本

# chmod +x sum

# ./sum 1 2 3 4 5 6 7 8         # 累加1-8
3.3 处理选项

使用shift命令移动位置参数,从而处理多个简单选项

# !/bin/bash           

while [ -n "$1" ]               # 通过循环,遍历$1位置参数
do
    case "$1" in                # 使用case命令,匹配$1位置上的选项
    "-a")                       # 变量值最好用双引号括起来,关键字用小括号括起来
        echo 'Option a'         # 若命令行输入-a,则命中,本行可写入相关选项逻辑
        ;;                      # 每个类别结尾使用两个连续的分号来处理
    "-b")  
        echo 'Option b'         # 若命令行输入-b,则命中,本行可写入相关选项逻辑
        ;;      
    "-c") 
        echo 'Option c'         # 若命令行输入-c,则命中,本行可写入相关选项逻辑
        ;;      
    esac
    shift                       # 把$2位置参数向前移动到$1,原$1位置参数不可用
done
3.4 分离参数和选项

使用shift命令移动位置变量,分离参数和选项

# !/bin/bash           

while [ -n "$1" ]               # 通过循环,遍历$1位置参数
do
    case "$1" in                # 使用case命令,匹配$1位置上的选项
    "-a")                       # 变量值最好用双引号括起来,关键字用小括号括起来
        echo 'Option a'         # 若命令行输入-a,则命中,本行可写入相关选项逻辑
        ;;                      # 每个类别结尾使用两个连续的分号来处理
    "-b")  
        echo 'Option b'         # 若命令行输入-b,则命中,本行可写入相关选项逻辑
        ;;      
    "-c") 
        echo 'Option c'         # 若命令行输入-c,则命中,本行可写入相关选项逻辑
        ;; 
    # 分离参数和选项
    "--")                       # --作为选项的结束
         shift                  # 左移$1位置变量,$2位置变量向前移动到$1
         break                  # 跳出循环
         ;;     
    esac
    shift                       # 把$2位置变量向前移动到$1,原$1位置变量不可用
done

echo "params are $*"            # 输出所有参数
3.5 处理带值选项

使用shift命令移动位置参数,获取选项的值

# !/bin/bash           

while [ -n "$1" ]               # 通过循环,遍历$1位置参数
do
    case "$1" in                # 使用case命令,匹配$1位置上的选项
    "-a")                       # 变量值最好用双引号括起来,关键字用小括号括起来
        echo "Option a"         # 若命令行输入-a,则命中,本行可写入相关选项逻辑
        ;;                      # 每个类别结尾使用两个连续的分号来处理
    # 获取-b选项的值
    "-b") 
        value="$2"              # $2是-b选项所在的位置变量 
        echo "Option b, value is $value"   # 若命令行输入-b,则命中,本行输出-b选项的值
        shift                   # 由于-b选项的值占有了一个位置变量,为了读取剩余选项,需要左移一位                
        ;;      
    "-c") 
        echo "Option c"         # 若命令行输入-c,则命中,本行可写入相关选项逻辑
        ;; 
    # 分离参数和选项
    "--")                       # --作为选项的结束
         shift                  # 左移$1位置变量,$2位置变量向前移动到$1
         break                  # 跳出循环
         ;;     
    esac
    shift                       # 把$2位置变量向前移动到$1,原$1位置变量不可用
done

echo "params are $*"            # 输出所有参数
3.6 利用getopt处理参数
# man getopt

# getopt abcd -b -acd                # 指定parse语句abcd,告诉getopt可以解析abcd4个选项,后边跟要解析的选项-b -acd

# getopt abcd -b -acd param1 param2  # 使用getopt分离参数和选项

# getopt ab:cd -b -acd param1 param2 # 使用getopt处理带值选项;在b之后加:,表示-b选项带值

利用getopt分离带值选项和参数

# !/bin/bash           

set -- `getopt -q ab:c "$@"`    # 通过set --,把反引号``内执行结果返回命令行;-q选项表示quit,不输出错误;b:表示带值选项-b;$@表示原来cmd参数列表

while [ -n "$1" ]               # 通过循环,遍历$1位置参数
do
    case "$1" in                # 使用case命令,匹配$1位置上的选项
    "-a")                       # 变量值最好用双引号括起来,关键字用小括号括起来
        echo "Option a"         # 若命令行输入-a,则命中,本行可写入相关选项逻辑
        ;;                      # 每个类别结尾使用两个连续的分号来处理
    # 获取-b选项的值
    "-b") 
        value="$2"              # $2是-b选项所在的位置变量 
        echo "Option b, value is $value"   # 若命令行输入-b,则命中,本行输出-b选项的值
        shift                   # 由于-b选项的值占有了一个位置变量,为了读取剩余选项,需要左移一位                
        ;;      
    "-c") 
        echo "Option c"         # 若命令行输入-c,则命中,本行可写入相关选项逻辑
        ;; 
    # 分离参数和选项
    "--")                       # --作为选项的结束
         shift                  # 左移$1位置变量,$2位置变量向前移动到$1
         break                  # 跳出循环
         ;;     
    esac
    shift                       # 把$2位置变量向前移动到$1,原$1位置变量不可用
done

echo "params are $*"            # 输出所有参数

执行脚本

# ./getopt -ac -b 20 param1 param2 

# ./getopt -ac -b "value 10" param1 param2   # getopt不能处理包含空格的选项值
3.7 利用getopts处理参数

使用getopts处理参数虽然是方便,但仍然有小小的局限性:

  1. 选项参数的格式必须是-d val,而中间不能有空格,如-dval

  2. 所有选项必须写在参数的前面。因为getopts是从命令行前面开始处理,遇到非-开头的参数,或者选项参数结束标记–就中止了,如果中间遇到非选项的命令行参数,后面的选项参数就都取不到了

  3. 不支持长选项。如–debug

getops命令可以识别带空格值的选项和参数,并分离选项和参数

# !/bin/bash           

# 使用getopts识别输入选项
while getopts ab:c opt           # 识别选项,赋给变量opt,开始while遍历;字符串ab:c是选项列表,每个字母代表一个选项,带值选项后面有:;不带:的是开关型选项(true/false),不需要指定选项值,cmd命令含有开关型选项就表示true
do
    case "$opt" in                 # 使用case命令,条件匹配变量$opt
    "a")                                   # 若命令行输入-a,则命中
        echo 'Option a'                    # 选项-a的逻辑
        ;;                      
    "b")  
        echo "Option b value : $OPTARG"    # 若命令行输入-b,则命中;通过getopts的环境变量$OPTARG,输出当前-b选项的值
        ;;      
    "c")                                   # 若命令行输入-c,则命中
        echo 'Option c'                    # 选项-c的逻辑
        ;;  
    "*") 
        echo 'unknown option: $opt'        # 如果输入了选项列表之外的选项,输出提示“unknown option :未知选项”
        ;;      
    esac
done
echo "$OPTIND"                             # getopts环境变量$OPTIND,存放当前选项在参数列表中的位置;getopts起始值是1,处理一个开关型选项,OPTIND加1,而处理一个带值选项,OPTIND则会加2

# 完成选项识别后,读取剩余参数
shift $[ $OPTIND - 1]                      # [$OPTIND - 1]表示当前选项的位置参数值,对选项列表进行左移操作;shift左移选项位置后,剩余参数正好到$1位置    

count=1
for param in "$@"                          # 遍历参数列表
do
    echo "param $count : $param"           # 输出参数值     
    count=$[ $count + 1] 
done
# ./getopts -ac -b "value 123"  "param1 123" param2  # 分离选项和参数
3.8 Linux常用默认选项含义

这里写图片描述

这里写图片描述

这里写图片描述

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值