zoukankan      html  css  js  c++  java
  • Learning_the_bash_Shell_Third_Edition 11/n

    for|case|select|while and until

    Command-Line Options and Typed Variables

    Command-Line Options

     

    Typical UNIX commands have the form command [-options]args, meaning that there can be 0 or more options. If a shell script processes the command teatime alice hatter, then $1 is “alice” and $2 is “hatter”. But if the command is teatime -o alice hatter, then $1 is -o, $2 is “alice”, and $3 is “hatter”.

     You might think you could write code like this to handle it:

    if [ $1 = -o ]; then
    code that processes the -o option
    1=$2
    2=$3
    fi
    normal processing of $1 and $2...
    

      

    But this code has several problems. First, assignments like 1=$2 are illegal because positional parameters are read-only. Even if they were legal, another problem is that this kind of code imposes limitations on how many arguments the script can handle—which is very unwise. Furthermore, if this command had several possible options, the code to handle all of them would get very messy very quickly.

     shift

    The getopts built-in command, which we will introduce later, provides this help.

    if [ -n "$(echo $1 | grep '^-[0-9][0-9]*$')" ]; then
    howmany=$1
    shift
    elif [ -n "$(echo $1 | grep '^-')" ]; then
    print 'usage: highest [-N] filename'
    exit 1
    else
    howmany="-10"
    fi
    filename=$1
    sort -nr $filename | head $howmany
    

      

    This uses the grep search utility to test if $1 matches the appropriate pattern. To do this we provide the regular expression ^-[0-9][0-9]*$ to grep, which is interpreted as “an initial dash followed by a digit, optionally followed by one or more digits.” If a match is found then grep will return the match and the test will be true, otherwise grep will return nothing and processing will pass to the elif test. Notice that we have enclosed the regular expression in single quotes to stop the shell from interpreting the $ and *, and pass them through to grep unmodified.

    For the sake of concreteness, assume that our script is called alice and we want to handle the options -a, -b, and -c:

    while [ -n "$(echo $1 | grep '-')" ]; do
      case $1 in
        -a ) process option -a ;;
        -b ) process option -b ;;
        -c ) process option -c ;;
        * ) echo 'usage: alice [-a] [-b] [-c] args...'
          exit 1
      esac
      shift
    done normal processing of arguments...

      

    #shift在干什么?let's see

    cor@debian:~/shell/mar5$ cat 2.sh 
    echo "=================="
    echo ${#*}  #查看当前position 参数的个数
    echo 'position 1 = '${1:-None}  #如果有就返回,否则返回None
    echo 'position 2 = '${2:-None}
    echo 'position 3 = '${3:-None}
    echo "========1========"
    shift
    echo ${#*}
    echo 'position 1 = '${1:-None}
    echo 'position 2 = '${2:-None}
    echo 'position 3 = '${3:-None}
    shift
    echo "========2========"
    echo 'position 1 = '${1:-None}
    echo 'position 2 = '${2:-None}
    echo 'position 3 = '${3:-None}
    shift
    echo ${#*}
    echo "========3========"
    echo 'position 1 = '${1:-None}
    echo 'position 2 = '${2:-None}
    echo 'position 3 = '${3:-None}
    

      result:

    cor@debian:~/shell/mar5$ . 2.sh a b c 
    ==================
    3 #第一次的总数是3
    position 1 = a
    position 2 = b
    position 3 = c
    ========1========
    2 # shift 后原来的 $1 被remove 掉了,后面的往前顶
    position 1 = b
    position 2 = c
    position 3 = None #此时,position 3 的返回值是None
    ========2========
    position 1 = c
    position 2 = None
    position 3 = None
    0
    ========3========
    position 1 = None
    position 2 = None
    position 3 = None
    

      

    Options with Arguments

    Assume that, in our alice script, the option -b requires its own argument. Here is the modified code that will process it:

    while [ -n "$(echo $1 | grep '-')" ]; do
    case $1 in
    -a ) process option -a ;;
    -b ) process option -b
    $2 is the option's argument
    shift ;;
    -c ) process option -c ;;
    * ) echo 'usage: alice [-a] [-b barg] [-c] args...'
    exit 1
    esac
    shift
    done
    normal processing of arguments...
    

      

    getopts

    So far, we have a complete, but constrained, way of handling command-line options.The above code does not allow a user to combine arguments with a single dash, e.g., -abc instead of -a -b -c. It also doesn’t allow one to specify arguments to options without a space in between, e.g., -barg in addition to -b arg.

    getopts takes two arguments. The first is a string that can contain letters and colons.Each letter is a valid option; if a letter is followed by a colon, the option requires an argument. getopts picks options off the command line and assigns each one (without the leading dash) to a variable whose name is getopts’s second argument. As long as there are options left to process, getopts will return exit status 0; when the options are exhausted, it returns exit status 1, causing the while loop to exit.

    while getopts ":ab:c" opt; do
      case $opt in
        a ) process option -a ;;
        b ) process option -b
            $OPTARG is the option's argument ;;
        c ) process option -c ;;
        ? ) echo 'usage: alice [-a] [-b barg] [-c] args...'
        exit 1
      esac
    done
    shift $(($OPTIND - 1))
    normal processing of arguments...
    

      

  • 相关阅读:
    20145312 《信息安全系统设计基础》实验三 实时系统的移植(修改版)
    20145312《信息安全系统设计基础》课程总结
    《信息安全系统设计基础》实验三 《实时系统的移植》 问题总结
    《信息安全系统设计基础》实验五 《网络通信》 问题总结

    20145309 《网络对抗技术》信息搜集与漏洞扫描
    20145309李昊《网络对抗》MSF应用基础
    20145309 《网络攻防》恶意代码分析
    20145309《网络对抗技术》免杀原理与实践
    20145309 李昊 《网络攻防》 Exp2 后门原理与实践
  • 原文地址:https://www.cnblogs.com/winditsway/p/14481212.html
Copyright © 2011-2022 走看看