Best way to parse command line args in Bash?

前端 未结 2 1296
半阙折子戏
半阙折子戏 2020-11-30 07:11

After several days of research, I still can\'t figure out the best method for parsing cmdline args in a .sh script. According to my references the getopts cmd is the way to

2条回答
  •  醉酒成梦
    2020-11-30 07:30

    If you want to avoid using getopt you can use this nice quick approach:

    • Defining help with all options as ## comments (customise as you wish).
    • Define for each option a function with same name.
    • Copy the last five lines of this script to your script (the magic).

    Example script: log.sh

    #!/bin/sh
    ## $PROG 1.0 - Print logs [2017-10-01]
    ## Compatible with bash and dash/POSIX
    ## 
    ## Usage: $PROG [OPTION...] [COMMAND]...
    ## Options:
    ##   -i, --log-info         Set log level to info (default)
    ##   -q, --log-quiet        Set log level to quiet
    ##   -l, --log MESSAGE      Log a message
    ## Commands:
    ##   -h, --help             Displays this help and exists
    ##   -v, --version          Displays output version and exists
    ## Examples:
    ##   $PROG -i myscrip-simple.sh > myscript-full.sh
    ##   $PROG -r myscrip-full.sh   > myscript-simple.sh
    PROG=${0##*/}
    LOG=info
    die() { echo $@ >&2; exit 2; }
    
    log_info() {
      LOG=info
    }
    log_quiet() {
      LOG=quiet
    }
    log() {
      [ $LOG = info ] && echo "$1"; return 1 ## number of args used
    }
    help() {
      grep "^##" "$0" | sed -e "s/^...//" -e "s/\$PROG/$PROG/g"; exit 0
    }
    version() {
      help | head -1
    }
    
    [ $# = 0 ] && help
    while [ $# -gt 0 ]; do
      CMD=$(grep -m 1 -Po "^## *$1, --\K[^= ]*|^##.* --\K${1#--}(?:[= ])" log.sh | sed -e "s/-/_/g")
      if [ -z "$CMD" ]; then echo "ERROR: Command '$1' not supported"; exit 1; fi
      shift; eval "$CMD" $@ || shift $? 2> /dev/null
    done
    

    Testing

    Running this command:

    ./log.sh --log yep --log-quiet -l nop -i -l yes
    

    Produces this output:

    yep
    yes
    

    By the way: It's compatible with posix!

提交回复
热议问题