I'm trying to better understand how to write bash scripts using positional parameters as arguments to the script. Specifically I want to understand how to make a script as user friendly as possible, capable of handling multiple arguments from any position. Much in that ls -lst is the same as ls -stl. I decided to attempt a password generator. I'm not very familiar with writing scripts that take arguments. After a while I just decided to do the whole thing using if statements. 
Note: to give credit where credit is due, the rand_string function in the script below came directly from this answer.
#!/bin/bash
## grep -v '##' will remove all the comments if you're so inclined :)
usage(){
echo "usage: $0 [n][-c]||[-h]"  
}
## Character set used to create random strings 
chars=( {a..z} {A..Z} {0..9} \! \" \# \$  \% \& \( \) \* \+ \, \- \. \/ \: \; \< \= \> \? \@ \[ \] \^ \_ \` \{ \| \} \~ \\ )
## Create random string from character set
rand_string() { 
    local c=$1 ret=
    while((c--)); do
        ret+=${chars[$((RANDOM%${#chars[@]}))]}; done
    printf '%s\n' "$ret"
}
## get a random number between 14-50
length() {
    python -S -c "import random; print random.randrange(14,50)"
}
## regular expression to test for valid numbers
re='^[0-9]+$'
## if no options specified 
## create a random string of charcters
## of a random length between 14-50 characters
## display password on screen and exit
if [ ! "$1" ]; then
    set - "$(length)"
    password="$(rand_string "$1")"
    echo "$password"
    exit
fi
## if option 1 or option 2 is -h or -help
## display usage and exit
if [[ "$1" == -h || "$1" == -help || "$2" == -h || "$2" == -help ]]; then
    usage
    exit
fi
## if more than 2 options
## exit with error code 1
if [[ $# -gt 2 ]]; then
    echo "Invalid number of options specified"
    usage
    exit 1
fi
## if exactly 2 options
if [[ $# -eq 2 ]]; then
    ## test if option 1 is a number
    ## if option 1 is NOT a number 
    if [[ ! "$1" =~ $re ]]; then
        ## test if option 1 is -c or -copy
        if [[ "$1" == -c || "$1" == -copy ]]; then
            ## if option 1 is -c or -copy
            ## test if option 2 is a number
            ## if 2 is a number and 1 is -c or -copy 
            ## execute the command
            if [[ "$2" =~ $re ]]; then
                set - "$(length)"
                rand_string "$1" | pbcopy
                echo "Password copied to clipboard"
                exit
            ## if option 1 is -c or -copy
            ## but option 2 is NOT a number
            ## exit script with error code 1
            elif [[ ! "$2" =~ $re ]]; then
                echo "Unrecognized option \"$2\""
                usage
                exit 1
            fi
        else
            echo "Unrecognized option \"$1\""
            exit 1
        fi
    ## if option 1 is a number
    elif [[ "$1" =~ $re ]]; then
        ## and option 2 is -c or -copy
        ## execute the command
        if [[ "$2" == -c || "$2" == -copy ]]; then
            rand_string "$1" | pbcopy
            echo "Password copied to clipboard"
            exit
        ## if option 1 is a number 
        ## but option 2 is not -c or -copy
        ## exit script with error code 1
        else
            echo "Unrecognized option \"$2\""
            usage
            exit 1
        fi
    fi
## if exactly one option specified
elif [[ $# -eq 1 ]]; then
    ## if option is NOT a number
    ## check if option is -c or -copy
    if [[ ! "$1" =~ $re ]]; then
        ## if option is -c or -copy
        ## execute the command 
        if [[ "$1" == -c || "$1" == -copy ]]; then
            set - "$(length)"
            rand_string "$1" | pbcopy
            echo "Password copied to clipboard"
            exit
        ## if option is neither a number nor -c or -copy
        ## exit script with error code 1
        else
            echo "Unrecognized option \"$1\""
            usage
            exit 1
        fi
    ## if option is a number
    ## execute the command
    elif [[ "$1" =~ $re ]]; then
        rand_string "$1"
    fi
fi
This script takes two optional arguments:
- any whole number e.g.. - 10,- 29,- 54to determine the length of string
- -cor- -copyto copy the string to the clipboard
- -hor- -helpto display the- usagefunction
Any of the above arguments can be called from the $1 or $2 position. Any of these arguments may also be omitted.
Assuming the script is called password any of the following are valid uses:
password 
password 25 
password -c
password 16 -copy
password -c 42
password -help 
But the script itself is a giant mess of if statements. It's long, messy and hard to read. 
So my question is: How could this be written to take the same arguments shown in valid uses without using so many if statements? 
I'm not asking anyone to rewrite my script. I'm just looking for some guidance to gain better understanding of how to do this correctly.
 
     
    