> ## Content Index
> Fetch the complete content index at: https://www.hackerstack.org/llms.txt
> Use this file to discover other available public pages before exploring further.

# How to easily create bash scripts that support options
- URL: https://www.hackerstack.org/how-to-easily-create-bash-script-that-support-options/
- Published: 2022-06-13T22:44:43.000Z
- Updated: 2025-06-13T20:09:57.000Z
- Description: Leverage the built-in getopt shell routine to create easy to use and extend Bash scripts that support options like many Linux command line utilities.
- Author: Gmkziz 👓
- Tags: Linux, #Import 2023-05-18 19:24, #Import 2023-11-26 01:16

#### Table of contents

- [Sample script](https://www.hackerstack.org/how-to-easily-create-bash-script-that-support-options/#sample-script)
- [Benefits of using getopt](https://www.hackerstack.org/how-to-easily-create-bash-script-that-support-options/#benefits-of-using-getopt)
- [How getopt works ?](https://www.hackerstack.org/how-to-easily-create-bash-script-that-support-options/#how-getopt-works)
- [Using getopt to implement the sample script](https://www.hackerstack.org/how-to-easily-create-bash-script-that-support-options/#using-getopt-to-implement-the-sample-script)

### Sample script

Lets say we want to create a bash script called `archive-project.sh` to archive a [Gitlab](https://about.gitlab.com/?ref=hackerstack.org) project repository. Here is how we want the script to be usable:

```
(bash)$ ./archive-project.sh -h

Archive Gitlab project repository

Usage :
> ./archive-project.sh --id <project-id> -u <gitlab-url> --token <gitlab-token>

Options :

-h, --help               Show help on how to use this script
--id                     ID of the project to archive
-u, --url                URL of the Gitlab instance where the project resides
-t, --token              User API token to use for authentication. 
                         The user  generating the API token need to have
                         'Owner' privilege on the project to archive

```

As you can see, the script users will be able to set options to tell the script which project to archive, on which Gitlab instance, using which authentication token. `getopt` can be very useful in achieving that. We will see how, keep reading 😉

### Benefits of using getopt

The `getopt` shell routine can be very useful to create shell scripts that support options. `getopt` will take care of the following for you:

- check and validate your predefined options
- recognize your short (`-s` for instance), long (`--my-long-option`) or alternate (`-myoption`) options
- check and validate options arguments when required
- exit with error code different from *0* when something goes wrong (required option argument not set, undefined options passed to the script...)
- print precise error messages (in your locales configured language)
- ability to disable error message printing in order to print your custom messages

### How getopt works ?

When using `getopt`, two parts separated by `--` can be identified. The first part is where we customize `getopt` behavior by using some of its options to tell which predefined options we want our scripts to support, on which form we want them to be (long: `--something`, short: `-b` ...), do they have required parameters, and so on.

The second part is the script arguments array that `getopt` will parse to recognize our predefined options and do some treatments. That second part is generally retrieved inside bash scripts with `"$@"` variable, which stores the bash script arguments.

Here is the `getopt` command line to use inside the `archive-project.sh` sample script:

```
getopt -s 'bash' -o 'h,u,t' -a -l 'help,id:,url:,token:' -n 'archive-project.sh' -- "$@"

```

In the above `getopt` command, we used the following options:

- `--name, -n`: the name of the script that will be used by `getopt` when reporting some errors... for instance, when detecting unrecognized options in bash scripts arguments.  
**Ex :** *archive-project.sh : unrecognize option '--fakeoption'*
- `--shell, -s`: represents the type of shell we will use `getopt` in for parsing scripts arguments... can be `bash` or `tcsh`
- `--longoptions, -l`: tell `getopt` to recognize the comma separated long options we specified... the `:` at the end of each option tell `getopt` that arguments are required for those options. We can also use `::` instead to tell `getopt` that we want argument to be optional for a specific options.
- `-a, --alternative`: allow long options to start with a single `-`. This means that using `-token` for instance when using the script will also work in addition to `--token`. When parsing the script args, you have to use the long options form (`--token`) in the `while/case` loop... `-token` won't be recognize...
- `-o, --options`: short options

We can also use `-q` option in the preceding `getopt` command line if we don't want to print built-in error messages. Not using the `-q` option makes `getopt` prints error messages when users :

- call the script with an undefined option
- call the script with a defined option but whitout argument, when one is required
- for an error related to `getopt` itself

**Example error messages**

```
(bash)$ ./archive-project.sh --id
archive-project.sh: option '--id' requires an argument

(bash)$ ./archive-project.sh --non-existent-option
archive-project.sh: unrecognized option '--non-existent-option'

```

### Using getopt to implement the sample script

In this section we will demonstrate how to implement the behavior defined for the `archive-project.sh` script and see in practice, how user friendly scripts that are easily configurable and extendable could be built by leveraging `getopt` features.

As a reminder, here is how we want the script to be usable:

```
(bash)$ ./archive-project.sh -h

Archive Gitlab project repository

Usage :
> ./archive-project.sh -id <project-id> -u <gitlab-url> --token <access-token>

Options :

-h, --help               Show help on how to use this script
-id, --project-id        ID of the project to archive
-u, --gitlab-url         URL of the Gitlab instance where the project resides
-t, --access-token       User API token to use for authentication. 
                         The user  generating the API token need to have
                         'Owner' privilege on the project to archive

```

As you can see, it is easily configurable thanks to options. Adding new features simply means new options for users, which is very user friendly.

In the first part of the script we define functions:

```
#!/bin/bash

# Print usage
usage() {
  echo -e "\nArchive Gitlab project repository \n"
  echo -e "Usage : $0 -id <project-id> -u <gitlab-url> --token <access-token> \n"
  echo -e "Options : \n"
  echo -e "-h, --help               \t Show help on how to use this script"
  echo -e "-id, --project-id        \t ID of the project to archive"
  (...)
  exit 1
}

# Archive project
archive_project()
{
  gitlab_url=$1    # value taken from the first argument of the function
  project_id=$2    # value taken from the second argument of the function
  access_token=$3  # value taken from the third argument of the function
  
  # code to archive Gitlab project here
}

```

The `usage` function will be called when the script is run whithout arguments or with the `-h` option. The `archive_project` function will be called when users properly set each of the options required to archive a Gitlab project.

Here is the remaining part of the `archive-project.sh` script devided into multiple pieces:

#### Piece #1

```
# getopt command used to add option support
GETOPT=$(getopt -s 'bash' -o 'h,u:,t:' -a -l 'help,id:,url:,token:' -n 'archive-project.sh' -- "$@")

# If there is any error with the previous getopt command,
# an explicit error message will be printed by getopt and
# the script will exit
if [ $? -ne 0 ]; then
    exit 1
fi

# If no argument is provided print usage and exit
if [[ -z "$@" ]] ; then usage ; exit 1 ; fi

```

#### Piece #2

```
eval set -- "$GETOPT"

```

- Sets the value of positional arguments (`$@`) to the value of `GETOPT` variable
- This is done only when the `getopt` command in **Piece #1** succeeds
- The `GETOPT` variable will simply contain all arguments passed to the script plus the `--` at the end. Example :

```
# Script execution command
(bash)# ./archive-project.sh -id 152 --gitlab-url https://gitlab.hackerstack.org --access-token mytoken

# GETOPT variable resulting content
-id '152' --gitlab-url 'https://gitlab.hackerstack.org' --access-token 'mytoken

```

#### Piece #3

```
while true; do
    case "$1" in
        -h|--help)
            usage
        ;;
        --id)
            id=$2
            shift 2;
        ;;
        -u|--gitlab-url)
            url=$2
            shift 2;
        ;;
        -t|--access-token)
            token=$2
            shift 2;
        ;;
        --)
            shift ;
            break ;
        ;;
    esac
done

# Exploit parsed options arguments to archive the Gitlab project
archive_project $url $id $token

```

- Retrives options arguments from positional arguments (contained in `$@`) thanks to a `while/case` loop.
- For each valid option present in the script arguments, do something. For the `-h` or `--help` options for instance, call the `usage` function
- For each of the others options, set their arguments values to a new variable and move to the next option in the positional argument (`shift 2`)
- We are at the end of the positional arguments when the `--` argument is retrieved. It's time to exit the loop (`shift` \+ `break`) and exploit the saved options values
- The users inputs required to archive a Gitlab project, passed through the corresponding options are now saved in the `url`, `id` and `token` variables and can be passed to the `archive_project` function to archive the corresponding project

And voilà ! Now you know how to build bash utilities that are user friendly, configurable and easily extendable thanks to flags support added with `getopt`