bash argument case for args in $@

后端 未结 5 1680
无人共我
无人共我 2021-02-02 12:14

I have a script with a long list of OPTIONAL arguments. some have associated values.

Such as:

.script --first 2012-12-25 --last 2012-12-26 --copy --remov         


        
相关标签:
5条回答
  • 2021-02-02 12:22

    getopts cannot have optional arguments it seems. otherwise great.

    my solution

    loop the $@ and setting a variable equal to x=$arg do the case switch on that variable (rather than arg)

    that worked fine for arguments of the type --startdate 2012-12-25 --enddate 2012-12-29

    but did not work for --remove that has no following argument.

    therefore tack on stuff (unlikely argument) onto the arg string.

    leaving the following

    argc="$@ jabberwhocky" 
    echo $argc
    x=0
    # x=0 for unset variable
    for arg in $argc
    do
       case $x in
            "--start" )
              STARTDATE=$arg ;;
            "--end" )
              ENDDATE=$arg ;;
            "--copy" )
              COPY=true;;
            "--remove" )
              REMOVE=true;;
    

    ... and so on....

        esac
        x=$arg
    done
    
    0 讨论(0)
  • 2021-02-02 12:30

    You can allow both --a=arg or -a arg options with a little more work:

    START_DATE="$(date '+%Y-%m-%d')";
    LAST_DATE="$(date '+%Y-%m-%d')";
    while [[ $# -gt 0 ]] && [[ "$1" == "--"* ]] ;
    do
        opt="$1";
        shift;              #expose next argument
        case "$opt" in
            "--" ) break 2;;
            "--first" )
               START_DATE="$1"; shift;;
            "--first="* )     # alternate format: --first=date
               START_DATE="${opt#*=}";;
            "--last" )
               LAST_DATE="$1"; shift;;
            "--last="* )
               LAST_DATE="${opt#*=}";;
            "--copy" )
               COPY=true;;
            "--remove" )
               REMOVE=true;;
            "--optional" )
               OPTIONAL="$optional_default";;     #set to some default value
            "--optional=*" )
               OPTIONAL="${opt#*=}";;             #take argument
            *) echo >&2 "Invalid option: $@"; exit 1;;
       esac
    done
    

    Note the --optional argument uses a default value if "=" is not used, else it sets the value in the normal way.

    0 讨论(0)
  • 2021-02-02 12:35

    If you have more than one option, and especially options with values mixed with options without values, let getopts do the work for you.

    0 讨论(0)
  • 2021-02-02 12:36

    Use shift in the end of each case statement.

    Quote from a bash manual:

    shift [n]

    The positional parameters from n+1 ... are renamed to $1 .... Parameters represented by the numbers $# down to $#-n+1 are unset. n must be a non-negative number less than or equal to $#. If n is 0, no parameters are changed. If n is not given, it is assumed to be 1. If n is greater than $#, the positional parameters are not changed. The return status is greater than zero if n is greater than $# or less than zero; otherwise 0.

    0 讨论(0)
  • 2021-02-02 12:41

    $@ is an array, & not a simple variable.

    You can capture it to a local variable as x=("$@") & then use array x with indices as 0 to ($# - 1).

    To access individual elements, use ${x[$i]}. You can NOT directly use ${@[$i]}, however.

    So instead of for arg in "$@" loop, you will have i=0; while [ $i -lt $# ]; do loop.

    0 讨论(0)
提交回复
热议问题