shell脚本传参

  • shell脚本通常有三种传参方式:
    • 手工处理
    • getopts
    • getopt

手工处理方式

  • 内置变量
    • $0 脚本文件名
    • $1—$9 穿入的第1—9个参数。第10个参数用${10}表示
    • $# 参数个数
    • $@ 参数列表
    • $*
    • $$ 脚本进程
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      # cat test.sh
      #!/bin/bash
      n=0
      for parameter in $@
      do
      echo "第$((++n))个参数值为:${parameter}"
      done

      # sh test.sh a b c d e
      第1个参数值为:a
      第2个参数值为:b
      第3个参数值为:c
      第4个参数值为:d
      第5个参数值为:e

getopts

getopts是由bash内置,不支持长参数选项,使用简单,不会重排所有参数的顺序。

  • 参数说明:
    1
    2
    3
    4
    5
    6
    7
    8
    所有选项参数必须写在其它参数的前面
    不支持长选项
    usage:
    getopts optstring name [arg]
    ":" 选项后面跟单个冒号表示该选项跟参数
    "$OPTARG" 内置变量,用于存放参数值
    "$OPTIND" 代表当前选项在参数列表中的位移。参数从1开始编号,getopts在处理参数的时候,处理一个开关型选项,OPTIND加1,处理一个带值的选项参数,OPTIND则会加2。

  • 范例
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    # cat getopts.sh
    #!/bin/bash

    while getopts "a:b:cd" args
    do
    echo -e "\$args:$args \t\$OPTARG:$OPTARG\t\$OPTIND:$OPTIND"
    case $args in
    a)
    echo "$args's arg:$OPTARG,\$OPTIND:$OPTIND"
    ;;
    b)
    echo "$args's arg:$OPTARG,\$OPTIND:$OPTIND"
    ;;
    c)
    echo "$args's arg:$OPTARG,\$OPTIND:$OPTIND"
    ;;
    d)
    echo "$args's arg:$OPTARG,\$OPTIND:$OPTIND"
    ;;
    #当遇到未定义的选项时args值为?
    #*)
    # echo "$args's arg:$OPTARG,\$OPTIND:$OPTIND"
    # exit 1
    esac
    done


    # 参数不被重新排序,当遇到不能被识别的参数"3"时,循环退出。
    # sh getopts.sh -a 1 -b 2 -c 3 -d 4
    $args:a $OPTARG:1 $OPTIND:3
    a's arg:1,$OPTIND:3
    $args:b $OPTARG:2 $OPTIND:5
    b's arg:2,$OPTIND:5
    $args:c $OPTARG: $OPTIND:6
    c's arg:,$OPTIND:6

    #参数合并
    # sh getopts.sh -a1 -b2 -cd
    $args:a $OPTARG:1 $OPTIND:2
    a's arg:1,$OPTIND:2
    $args:b $OPTARG:2 $OPTIND:3
    b's arg:2,$OPTIND:3
    $args:c $OPTARG: $OPTIND:3
    c's arg:,$OPTIND:3
    $args:d $OPTARG: $OPTIND:4
    d's arg:,$OPTIND:4

getopt

getopt是独立的可执行文件

  • 常用参数说明
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    −a, −−alternative           使getopt长参数支持"-"符号打头,必须与-l同时使用
    −l, −−longoptions 表示长选项,后面接getopt支持长参数列表,逗号分隔
    −n, −−name progname 如果getopt处理参数出错,返回错误提示
    −o, −−options shortopts 表示短选项,后面接短参数列表,这种用法与getopts类似。两个冒号表示该选项有一个可选参数,可选参数必须紧贴选项。
    −q, −−quiet 关闭错误输出
    −Q, −−quiet−output 关闭正常输出
    −s, −−shell shell 指定shell类型,"sh","bash","csh","tcsh".
    −u, −−unquoted 不给参数列表加引号,默认是加引号的(不使用-u选项)
    −T, −−test 测试getopt是增强版或旧版,不生成输出。
    −V, −−version
    −h, −−help
    $@ 参数本身的列表,也不包括命令本身
    ":" 选项后面跟单个冒号表示该选项必须跟参数
    "::" 选项后面跟两个冒号表示该选项可以跟参数
  • 范例
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    # cat getopt.sh
    #!/bin/bash

    OPTS=$(getopt -s bash -o x:y::z -a --long aaaa:,bbbb::,cccc -n 'warning' -- "$@")

    eval set -- "$OPTS"

    while true;
    do
    case "$1" in
    -x|--aaaa)
    echo -e "Hit $1,arg=$2"
    shift 2
    ;;
    -y|--bbbb)
    echo -e "Hit $1,arg=$2"
    shift 2
    ;;
    -z|--cccc)
    echo -e "Hit $1,arg=$2"
    shift
    ;;
    --)
    echo -e "Hit $1,arg=$2"
    shift;
    break
    ;;
    *)
    echo -e "\nNo parameters were hit.\n"
    break
    ;;
    esac
    done

    ## -cccc后没有冒号,实际执行中后面即使跟了参数也不会被接收
    # sh getopt.sh -aaaa 1 -bbbb=2 -cccc 3
    Hit --aaaa,arg=1
    Hit --bbbb,arg=2
    Hit --cccc,arg=--
    Hit --,arg=3

    ## 长参数类型中,可选参数必须由等号连接选项和参数,空格隔开无法接收
    # sh getopt.sh -aaaa 1 -bbbb 2 -cccc 3
    Hit --aaaa,arg=1
    Hit --bbbb,arg=
    Hit --cccc,arg=--
    Hit --,arg=2

    # sh getopt.sh -x 1 -y 2 -z
    Hit -x,arg=1
    Hit -y,arg=
    Hit -z,arg=--
    Hit --,arg=2

    ## 在短选项参数中,可选参数可紧跟选项传参,长选项中不支持
    # sh getopt.sh -aaaa 1 -bbbb2 -cccc 3
    warning:无法识别的选项“-bbbb2”
    Hit --aaaa,arg=1
    Hit --cccc,arg=--
    Hit --,arg=3

    ## sh getopt.sh -aaaa 1 -bbbb2 -cccc 3
    warning:无法识别的选项“-bbbb2”
    Hit --aaaa,arg=1
    Hit --cccc,arg=--
    Hit --,arg=3

    ##如果没有参数的选项后跟了参数,且不是在参数列表的最后位置,会导致参数错乱
    # sh getopt.sh -cccc 1 -bbbb=2 -aaaa 3
    Hit --cccc,arg=--bbbb
    Hit --bbbb,arg=2
    Hit --aaaa,arg=3
    Hit --,arg=1