Parse CLI Arguments with getopts and Long Options
Intermediate10 min
Handle short and long command-line options, required arguments, and positional parameters in bash scripts using getopts and case statements.
Prerequisites
- -Bash 4.0+
- -Basic bash scripting knowledge
Steps
1
Parse short options with getopts
Use the built-in getopts for simple short option parsing with flags and arguments.
$ cat > parse_args.sh << 'EOF'
#!/usr/bin/env bash
set -euo pipefail
VERBOSE=false
OUTPUT=""
while getopts ':hvo:' opt; do
case "$opt" in
h) echo "Usage: $0 [-v] [-o output] file"; exit 0 ;;
v) VERBOSE=true ;;
o) OUTPUT="$OPTARG" ;;
:) echo "Option -$OPTARG requires an argument" >&2; exit 1 ;;
?) echo "Unknown option: -$OPTARG" >&2; exit 1 ;;
esac
done
shift $((OPTIND - 1))
echo "Verbose: $VERBOSE, Output: $OUTPUT, Remaining: $*"
EOF
chmod +x parse_args.sh
The colon after an option letter (like o:) means that option requires an argument.
2
Add long option support with a case statement
Handle --long-option style flags using a while/case loop.
$ cat > parse_long.sh << 'EOF'
#!/usr/bin/env bash
set -euo pipefail
VERBOSE=false
OUTPUT=""
DRY_RUN=false
FILES=()
while [[ $# -gt 0 ]]; do
case "$1" in
-h|--help) echo "Usage: $0 [options] files..."; exit 0 ;;
-v|--verbose) VERBOSE=true; shift ;;
-o|--output) OUTPUT="${2:?'--output requires a value'}"; shift 2 ;;
-d|--dry-run) DRY_RUN=true; shift ;;
--) shift; FILES+=("$@"); break ;;
-*) echo "Unknown option: $1" >&2; exit 1 ;;
*) FILES+=("$1"); shift ;;
esac
done
echo "Verbose=$VERBOSE Output=$OUTPUT DryRun=$DRY_RUN Files=${FILES[*]}"
EOF
chmod +x parse_long.sh
3
Validate required arguments
Check that required options and positional arguments are provided.
$ echo '[[ -z "$OUTPUT" ]] && { echo "Error: --output is required" >&2; exit 1; }' && echo '[[ ${#FILES[@]} -eq 0 ]] && { echo "Error: at least one file required" >&2; exit 1; }'
4
Test the argument parser
Run the script with various option combinations to verify parsing.
$ ./parse_long.sh -v --output result.txt --dry-run file1.txt file2.txt
Full Script
FAQ
Discussion
Loading comments...