0

I have the following code in one of my scripts. I am trying to make the user usage as error proof as possible.

while getopts ":c:d:t:T:a:" opt; do
        case ${opt} in
                c )
                        currency=$OPTARG
                        ;;
                d )
                        cdate=$OPTARG
                        ;;
                t )
                        terms_arr=$OPTARG
                        ;;
                T )
                        tails_arr=$OPTARG
                        ;;
                a )
                        all=$OPTARG
                        ;;
                \? )
                        echo "Invalid Option: -$OPTARG" 1>&2
                        echo "Usage: -c [currency USD/JPY,U/J] -d [YYYYMMDD] -t [comma-sep list]\
                        -T [comma-sep list] -a [duplicate rows y/n]"
                        echo "  e.g. -c JPY -d 20150220 -t 1,2,3 -T 7,10,15 -a y"
                        exit 1
                        ;;
                : )
                        echo "Used option defaults......."
                        ;;
        esac
done

shift $((OPTIND -1))

if ! date -d "$cdate" >/dev/null 2>&1; then
        echo "error: Incorrect date specified.Correct format is YYYYMMDD.Please try again."
        exit 1
elif [ -z "$cdate" ]
then
        cdate=$(date +"%Y%m%d")
fi

if [ "$currency" = "JPY" ] || [ "$currency" = "J" ] || [ "$currency" = "j" ]
then
        currency="JPY"

elif [ "$currency" = "USD" ] || [ "$currency" = "U" ] || [ "$currency" = "u" ] || [ -z "$currency" ]
then
        currency="USD"

else
        echo "error: Currency should be USD/JPY" >&2
        exit 1
fi

if [ -z "$terms_arr" ]
then
        terms_arr="1,2,3"
elif ! [[ $terms_arr =~ ^([0-9]+,?)+$ ]]
then
        echo "error: terms $terms_arr.. can only be comma separated numbers. Please try again." >&2
        exit 1
fi

if [ -z "$tails_arr" ]
then
        tails_arr="7,10,15"
elif ! [[ $tails_arr =~ ^([0-9]+,?)+$ ]]
then
        echo "error: tails $tails_arr.. can only be comma separated numbers. Please try again." >&2
        exit 1
fi

if [ -z "$all" ]
then
        all="n"
fi

This works fine till there is some bad input.

-c J 20150222 -a y (yyyymmdd date entered without -d) makes the -a value unused. (default 'n' is taken). With this input I do need currency -c as 'JPY' but any options not entered (- d, -t, -T) should take the default values from the if conditions and then take the -a value 'y' entered.

-c J -t 1,2;3 -T 7;10,15 -a y   for comma separated lists -t, -T if I enter as shown (; typed in place of , ) the program exits with the message:

If '3' is not a typo you can run the following command to lookup the package that contains the binary:
    command-not-found 3
-bash: 3: command not found
If '10,15' is not a typo you can run the following command to lookup the package that contains the binary:
    command-not-found 10,15

Also was wondering if all this can be done in a better way with any other checks I missed.

I am aware that getopts doesn't support default value.

Apologies for the long post.

sunnyp101
  • 41
  • 3
  • 1
    If you want more functionality than getopts provides, then it isn't very difficult to create an alternative using `case` statements and `shift`.Then you have full control over how eveything on the command line is interpereted. –  Apr 10 '15 at 14:05
  • 1
    The `-c J 20150222 -a y` paragraph is rather confusing. The input is invalid, and invalid tokens SHOULD be barked at rather than silently ignored. (RFC SHOULD) – 4ae1e1 Apr 10 '15 at 16:45

0 Answers0