Passing arguments to a bash script
Published: 2022-02-27 07:52:59

> Short Options

```
./test.sh -a -b -c charlie -d river lorem ipsum
PARSED_ARGUMENTS is  -a -b -c=charlie -d=river -- 'lorem'
ALPHA   : 1
BETA    : 1 
CHARLIE : charlie
DELTA   : river
Parameters remaining are: lorem
```

> Long Options

```
./test.sh --alpha --beta --charlie=charlie --delta=river lorem
PARSED_ARGUMENTS is  --alpha --beta --charlie 'charlie' 
--delta 'river' -- 'lorem'
ALPHA   : 1
BETA    : 1 
CHARLIE : charlie
DELTA   : river
Parameters remaining are: lorem
```

The bash script is in [github](https://github.com/leroykayanda/miscellaneous/blob/main/params.sh).

-a and -b are called `switches` because they do not take any parameters while -c and -d to take parameters.

In the script, we first set some default values.

`ALPHA=unset
BETA=unset
CHARLIE=unset
DELTA=unset
`

The usage function will be used to show a user the expected inputs if they specify incorrect parameters.

```
usage()
{
  echo "Usage: k8s-setup [ -a | --alpha ] 
                        [ -b | --beta ]
                        [ -c | --charlie CHARLIE ] 
                        [ -d | --delta   DELTA   ] filename(s)"
  exit 2
}
```

We use `getopt` to get the parameters a user specifies.

`PARSED_ARGUMENTS=$(getopt -a -n k8s-setup -o abc:d: --long alpha,beta,charlie:,delta: -- "$@")`

We use a colon (:) to indicate that an argument expects a value e.g --charlie=charlie rather than just --charlie.

We have passed the -a option to getopt so that it accepts the single hyphen form of a switch i.e -charlie as well as --charlie are all accepted. With `-n k8s-setup`, k8s-setup is the script name. This is displayed if user input causes an error.

```
./test.sh --alpha --betas --charlie=charlie --delta river lorem 
k8s-setup: unrecognized option '--betas'
Usage: k8s-setup [ -a | --alpha ] 
                        [ -b | --beta ]
                        [ -c | --charlie CHARLIE ] 
                        [ -d | --delta   DELTA   ] filename(s)
```

This is more user friendly than.

```
./test.sh --alpha --betas --charlie=charlie --delta river lorem 
getopt: unrecognized option '--betas'
Usage: k8s-setup [ -a | --alpha ] 
                        [ -b | --beta ]
                        [ -c | --charlie CHARLIE ] 
                        [ -d | --delta   DELTA   ] filename(s)
```

If getopt accepts all inputs, it returns a status code of 0. This is how we catch errors.

```
VALID_ARGUMENTS=$?
if [ "$VALID_ARGUMENTS" != "0" ]; then
  usage
fi
```

The set command takes any arguments after the options (here “--” signals the end of the options) and assigns them to the positional parameters ($0.. $n)

```
eval set -- "$PARSED_ARGUMENTS"
```


```
while :
do
  case "$1" in
    -a | --alpha)   ALPHA=1      ; shift   ;;
    -b | --beta)    BETA=1       ; shift   ;;
    -c | --charlie) CHARLIE="$2" ; shift 2 ;;
    -d | --delta)   DELTA="$2"   ; shift 2 ;;
    # -- means the end of the arguments; drop this, and break out of the while loop
    --) shift; break ;;
    # If invalid options were passed, then getopt should have reported an error,
    # which we checked as VALID_ARGUMENTS when getopt was called...
    *) echo "Unexpected argument: $1 "
       usage ;;
  esac
done
```

Now we loop through the $1 variable. Each time we have processed a parameter, we use shift to push the parameter off the stack so that the next parameter is not at position $1. If a parameter has a value we use `shift 2` so that both the parameter and its argument are pushed off the stack. -- signifies that there are no more parameters and we break out of the loop. * captures any unexpected input and calls the usage function. Any parameters left on the stack are captured by $@.

References

[1. https://www.shellscript.sh/tips/getopt/index.html](https://www.shellscript.sh/tips/getopt/index.html)