getopts Command
Intermediate Shell Scripting man(1)Parse command-line options in shell scripts
📅 Updated: Mar 16, 2026
SYNTAX
getopts OPTSTRING VARIABLE [ARGS]
What Does getopts Do?
The getopts command is a built-in shell utility for parsing command-line options (flags) in bash and POSIX shell scripts. It processes single-character options like -v, -f filename, and -h, following Unix conventions for command-line argument handling.
getopts is the standard way to make shell scripts accept options professionally, just like compiled programs. It handles option bundling (-vf instead of -v -f), options with arguments (-f filename), error reporting for unknown options, and the -- end-of-options marker.
Every production shell script that accepts arguments should use getopts. It replaces manual $1/$2 parsing with a robust, standard approach that handles edge cases correctly. While getopt (external command, note the different name) supports long options (--verbose), getopts (built-in) is more portable and sufficient for most scripts.
getopts is the standard way to make shell scripts accept options professionally, just like compiled programs. It handles option bundling (-vf instead of -v -f), options with arguments (-f filename), error reporting for unknown options, and the -- end-of-options marker.
Every production shell script that accepts arguments should use getopts. It replaces manual $1/$2 parsing with a robust, standard approach that handles edge cases correctly. While getopt (external command, note the different name) supports long options (--verbose), getopts (built-in) is more portable and sufficient for most scripts.
Options & Flags
| Option | Description | Example |
|---|---|---|
| OPTSTRING | String of valid option characters (colon after = requires argument) | "vf:o:h" means -v, -f ARG, -o ARG, -h |
| VARIABLE | Variable to store the current option character | while getopts "vf:h" opt; do |
| $OPTARG | Contains the argument for the current option (if colon in optstring) | case $opt in f) file=$OPTARG ;; |
| $OPTIND | Index of the next argument to process | shift $((OPTIND - 1)) |
| Leading : | Silent error mode — suppress error messages | getopts ":vf:h" opt |
| ? | Matches unknown/invalid options | case $opt in ?) echo "Invalid: -$OPTARG" ;; |
Practical Examples
#1 Basic option parsing
Complete option parsing: -v (flag), -f file (with argument), -o output (with argument), -h (help). Shift removes parsed options leaving positional args.
$ #!/bin/bash
while getopts "vf:o:h" opt; do
case $opt in
v) verbose=true ;;
f) input_file=$OPTARG ;;
o) output_file=$OPTARG ;;
h) echo "Usage: $0 [-v] [-f file] [-o output] [-h]"; exit 0 ;;
*) echo "Invalid option: -$OPTARG" >&2; exit 1 ;;
esac
done
shift $((OPTIND - 1))#2 Script with verbose mode
Simple verbose flag. After getopts, $1 contains the first non-option argument.
$ #!/bin/bash
verbose=false
while getopts "v" opt; do
case $opt in v) verbose=true ;; esac
done
shift $((OPTIND - 1))
[ "$verbose" = true ] && echo "Processing: $1"
# do work with $1...#3 Required argument validation
Handle missing arguments (leading colon enables silent mode). Check required options after parsing.
$ #!/bin/bash
while getopts ":f:" opt; do
case $opt in
f) file=$OPTARG ;;
:) echo "Option -$OPTARG requires an argument" >&2; exit 1 ;;
?) echo "Unknown option: -$OPTARG" >&2; exit 1 ;;
esac
done
[ -z "$file" ] && echo "Error: -f is required" >&2 && exit 1#4 Backup script with options
A practical backup script accepting source, destination, compression flag, and verbose mode.
$ #!/bin/bash
usage() { echo "Usage: $0 -s source -d dest [-c] [-v]"; exit 1; }
while getopts "s:d:cvh" opt; do
case $opt in
s) src=$OPTARG ;; d) dst=$OPTARG ;;
c) compress=true ;; v) verbose=true ;;
h) usage ;; *) usage ;;
esac
done
[ -z "$src" ] || [ -z "$dst" ] && usage#5 Option bundling works
getopts handles bundled options: -cv is the same as -c -v. Options with arguments (-f) can be bundled too: -cvf input.txt.
$ ./script.sh -cv -f input.txtTips & Best Practices
Always shift after getopts: After the getopts loop, run: shift $((OPTIND - 1)). This removes parsed options, leaving only positional arguments in $1, $2, etc.
getopts vs getopt: getopts (built-in, POSIX) handles short options only. getopt (external, GNU) supports long options (--verbose). getopts is more portable; use getopt when you need long options.
Reset OPTIND for functions: OPTIND is global. If calling getopts in a function, set local OPTIND=1 first, or pass arguments explicitly to avoid conflicts with the main script.
Use leading colon for custom errors: Start optstring with : (e.g., ":vf:h") to suppress default error messages. Handle errors yourself in the ? and : cases for cleaner output.
Frequently Asked Questions
How do I parse command-line arguments in bash?
Use getopts in a while loop: while getopts "vf:h" opt; do case $opt in v) verbose=1 ;; f) file=$OPTARG ;; h) usage ;; esac; done; shift $((OPTIND-1))
Does getopts support long options (--verbose)?
No. getopts only supports single-character options (-v). For long options, use the external getopt command or parse manually with a case statement.
What does the colon after a letter mean in getopts?
A colon after a letter means that option requires an argument. "f:" means -f requires an argument (stored in $OPTARG). Without colon, it is a boolean flag.
How do I make an option required?
getopts does not enforce required options. Check after the loop: [ -z "$file" ] && echo "Error: -f required" && exit 1. This is the standard pattern.
Related Commands
More Shell Scripting Commands
Master Linux with Professional eBooks
Curated IT eBooks covering Linux, DevOps, Cloud, and more
Browse Books →