Tutorials

Bash Tutorial: getopts

The getopts command is a built-in shell command for parsing command line arguments. It's preferable to getopt for several reasons, including its definition in POSIX and its native implementation in Bash. With getopts, you don't need to rely on external programs or worry about the order of options. This tutorial will guide you through using getopts effectively in your Bash scripts.

Key Takeaways

  • getopts is preferred over getopt for command line parsing in Bash due to its native implementation and POSIX compliance.
  • getopts can handle options with and without parameters, as well as multiple arguments.
  • Starting the option string with a colon enables silent error mode, suppressing default error messages.

Basic Example with getopts

Consider a simple script sample.sh that takes an option a:

$ ./sample.sh -a

Here's how you can implement it:

#!/bin/bash
while getopts "a" opt; do
case $opt in
a)
echo "argument -a called" >&2
;;
esac
done

This script will output:

argument -a called

The getopts command operates within a while loop, iterating through each option in the provided string, which in this case is "a".

Option with Parameter

If you want option a to accept a parameter:

$ ./sample.sh -a hello

Here's how it can be implemented:

#!/bin/bash
while getopts "a:" opt; do
case $opt in
a)
echo "argument -a called with parameter $OPTARG" >&2
;;
esac
done

The output will be:

argument -a called with parameter hello

A colon following a character in the options string indicates that the option expects a parameter.

Understanding Default Errors

If a parameter is not passed for option a, Bash produces:

./sample.sh: option requires an argument -- a

For better error handling, start the options string with a colon to enable "silent error mode":

#!/bin/bash
while getopts ":a:" opt; do
case $opt in
a)
echo "argument -a called with parameter $OPTARG" >&2
;;
esac
done

This suppresses the default error output when a required parameter is missing.

Custom Error Handling

In silent mode, you might want to provide custom error messages:

#!/bin/bash
while getopts ":a:" opt; do
case $opt in
a)
echo "argument -a called with parameter $OPTARG" >&2
;;
?)
echo "Invalid option: $OPTARG" >&2
;;
esac
done

With this script, if a needed parameter is absent, you'll see:

Invalid option: a

Handling Multiple Arguments

You can manage multiple arguments easily. For instance, with options a and b:

$ ./sample.sh -a hello -b

Implementation:

#!/bin/bash
while getopts ":a:b" opt; do
case $opt in
a)
echo "argument -a called with parameter $OPTARG" >&2
;;
b)
echo "argument -b called" >&2
;;
?)
echo "Invalid option: $OPTARG" >&2
;;
esac
done

This outputs:

argument -a called with parameter hello
argument -b called

Note that b is an option without a parameter, unlike a.

Conclusion

getopts is the practical choice for handling command line arguments in Bash. It's typically embedded in a while loop to process options, with a colon indicating parameter expectations. Starting the options string with a colon activates silent mode, helping you better manage script output.

FAQ

What is the difference between getopts and getopt?

getopts is a built-in command in Bash and is POSIX-compliant, while getopt is an external command with inconsistent behavior across systems.

How do you handle options without parameters?

Simply omit the colon for options not requiring parameters, like the b option in the examples.

Can getopts handle long options like --help?

No, getopts only supports single-character options. For long options, you'll need a different approach, like using a custom parsing script or an alternative utility.

Mastering the tech interviewWhat everyone is doing wrong in tech interviews