Análisis de flags y argumentos con getopts
Implemente interfaces de línea de comandos profesionales con getopts para opciones cortas, argumentos obligatorios y mensajes de uso.
Análisis de flags y argumentos con getopts es una lección gratuita de Linux Command Line & Bash Scripting Mastery en CoddyKit. Esta es la lección 3 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Linux Command Line & Bash Scripting Mastery, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Linux Command Line & Bash Scripting Mastery incluye 4 lecciones en total.
Por qué existe getopts
Todo script del mundo real acaba necesitando aceptar opciones como -v, -o output.txt o -n 5. Analizarlas manualmente con $1, $2… se vuelve frágil enseguida.
getopts es el comando integrado estándar de POSIX que gestiona de forma fiable las opciones cortas (-a, -b), incluidas las que reciben un argumento. Está integrado en todos los shells POSIX, por lo que no requiere dependencias.
- Gestiona indicadores combinados:
-vn 5=-v -n 5 - Informa de las opciones desconocidas correctamente
- Establece automáticamente las variables estándar
OPTINDyOPTARG
En esta lección creará desde cero una CLI completa y profesional con getopts.
La sintaxis de getopts
La sintaxis básica consiste en un bucle while que llama a getopts en cada iteración:
while getopts "optstring" varname; do
case "$varname" in
...
esac
done- optstring — cadena que enumera cada letra de opción aceptada. Los dos puntos después de una letra indican que esa opción requiere un argumento.
- varname — recibe la letra de la opción actual en cada iteración.
- OPTARG — se establece automáticamente con el valor del argumento cuando hay dos puntos después de la letra.
- OPTIND — índice del siguiente argumento que se procesará; después del bucle, use
shift $((OPTIND - 1))para dejar disponibles los parámetros posicionales restantes.
#!/usr/bin/env bash
# Minimal skeleton — shows the loop structure
while getopts 'vn:' opt; do
case "$opt" in
v) echo "Verbose mode on" ;;
n) echo "Count = $OPTARG" ;;
?) echo "Unknown option: -$OPTARG" >&2; exit 1 ;;
esac
doneDefinir un optstring
El optstring es una declaración compacta del contrato de su CLI. Cada carácter representa un indicador aceptado.
'abc'— acepta-a,-by-c(sin argumentos)'a:bc'—-arequiere un argumento;-by-cno lo requieren':abc'— los dos puntos iniciales activan el modo de error silencioso (el script gestiona las opciones incorrectas en lugar de que el shell muestre un mensaje)
El modo silencioso es preferible en los scripts de producción porque le proporciona control total sobre los mensajes de error y los códigos de salida.
#!/usr/bin/env bash
# optstring ':o:vq'
# -o requires an argument (output file)
# -v verbose flag (no argument)
# -q quiet flag (no argument)
# Leading ':' = silent error mode
while getopts ':o:vq' opt; do
case "$opt" in
o) OUTPUT="$OPTARG" ;;
v) VERBOSE=1 ;;
q) QUIET=1 ;;
:) echo "Error: -$OPTARG requires an argument" >&2; exit 1 ;;
\?) echo "Error: unknown option -$OPTARG" >&2; exit 1 ;;
esac
done
echo "OUTPUT=$OUTPUT VERBOSE=$VERBOSE QUIET=$QUIET"OPTARG y los argumentos obligatorios
Cuando un indicador va seguido de dos puntos en el optstring, getopts almacena su valor en OPTARG. El usuario puede escribir el argumento con o sin espacio:
-o report.txt-oreport.txt
Ambas formas se analizan de manera idéntica. Esta es una de las principales ventajas frente al análisis manual con $1/shift.
En el modo silencioso (con ':' al principio del optstring), si falta un argumento, getopts establece varname en : y OPTARG en la letra de la opción, lo que resulta perfecto para mostrar un mensaje de error específico.
#!/usr/bin/env bash
# Demonstrate OPTARG with a file-processing script
while getopts ':i:o:' opt; do
case "$opt" in
i) INPUT="$OPTARG" ;;
o) OUTPUT="$OPTARG" ;;
:) echo "Error: option -$OPTARG needs a value" >&2; exit 1 ;;
\?) echo "Error: unknown flag -$OPTARG" >&2; exit 1 ;;
esac
done
echo "Input : ${INPUT:-<not set>}"
echo "Output : ${OUTPUT:-<not set>}"Pasar las opciones con OPTIND
Cuando getopts termina, OPTIND contiene el índice del primer argumento que no es una opción. Use shift para eliminar todas las opciones procesadas, de modo que $1, $2… hagan referencia a los parámetros posicionales restantes (por ejemplo, los nombres de archivo).
La forma habitual es siempre:
shift $((OPTIND - 1))Después del desplazamiento, $@ contiene únicamente los argumentos que no eran indicadores: los operandos de su comando.
#!/usr/bin/env bash
# Shows OPTIND shift and leftover positional args
VERBOSE=0
while getopts ':vn:' opt; do
case "$opt" in
v) VERBOSE=1 ;;
n) COUNT="$OPTARG" ;;
:) echo "Error: -$OPTARG requires an argument" >&2; exit 1 ;;
\?) echo "Error: unknown option -$OPTARG" >&2; exit 1 ;;
esac
done
shift $((OPTIND - 1))
echo "VERBOSE=$VERBOSE COUNT=${COUNT:-1}"
echo "Remaining args: $*"Escribir una función de uso
Un script profesional siempre proporciona una función usage() que muestra un mensaje de ayuda y termina. La convención es:
- Mostrarlo en stderr (fd 2) para no contaminar la salida redirigida mediante tuberías
- Salir con el código 0 para
-h/--helpy con el código 1 para un uso no válido - Llamar a
usage 1en las rutas de error y ausage 0en el gestor de-h
#!/usr/bin/env bash
usage() {
cat >&2 <<EOF
Usage: $(basename "$0") [-v] [-n COUNT] [-o FILE] [FILE...]
Options:
-v Verbose output
-n COUNT Repeat COUNT times (default: 1)
-o FILE Write output to FILE
-h Show this help
EOF
exit "${1:-0}"
}
while getopts ':vn:o:h' opt; do
case "$opt" in
v) VERBOSE=1 ;;
n) COUNT="$OPTARG" ;;
o) OUTFILE="$OPTARG" ;;
h) usage 0 ;;
:) echo "Error: -$OPTARG requires a value" >&2; usage 1 ;;
\?) echo "Error: unknown option -$OPTARG" >&2; usage 1 ;;
esac
done
shift $((OPTIND - 1))
echo "Parsed OK — verbose=${VERBOSE:-0} count=${COUNT:-1} out=${OUTFILE:--}"Valores predeterminados y validación
Después del análisis, valide las entradas y establezca los valores predeterminados antes de realizar cualquier trabajo real. Mantenga separadas la fase de análisis (el bucle) y la fase lógica. Esto facilita la lectura y las pruebas de ambas secciones.
- Use
${VAR:-default}para establecer valores predeterminados en línea - Valide los argumentos numéricos con una expresión regular o una comprobación aritmética
- Compruebe que las opciones obligatorias se hayan proporcionado realmente
#!/usr/bin/env bash
usage() { echo "Usage: $(basename "$0") -n COUNT [-v]" >&2; exit 1; }
VERBOSE=0
COUNT=''
while getopts ':n:v' opt; do
case "$opt" in
n) COUNT="$OPTARG" ;;
v) VERBOSE=1 ;;
:) echo "Error: -$OPTARG needs a value" >&2; usage ;;
\?) echo "Error: -$OPTARG unknown" >&2; usage ;;
esac
done
shift $((OPTIND - 1))
# Validation phase
[[ -z "$COUNT" ]] && { echo "Error: -n COUNT is required" >&2; usage; }
[[ "$COUNT" =~ ^[0-9]+$ ]] || { echo "Error: COUNT must be a positive integer" >&2; usage; }
for (( i=1; i<=COUNT; i++ )); do
[[ $VERBOSE -eq 1 ]] && echo "Iteration $i of $COUNT"
echo "Hello, world!"
doneCombinar indicadores en la línea de comandos
getopts gestiona automáticamente los indicadores cortos combinados escritos sin espacios, según la convención estándar de Unix:
-v -qequivale a-vq-n 5 -vequivale a-n5 -vo-vn5
No necesita escribir código adicional para admitir esta sintaxis: getopts recorre automáticamente cada carácter de una cadena de opciones combinadas. Esta es otra razón importante para usar getopts en lugar del análisis manual.
#!/usr/bin/env bash
# Test combined flag parsing
# Run as: bash script.sh -vq -n3
VERBOSE=0; QUIET=0; COUNT=1
while getopts ':vqn:' opt; do
case "$opt" in
v) VERBOSE=1 ;;
q) QUIET=1 ;;
n) COUNT="$OPTARG" ;;
:) echo "Error: -$OPTARG needs value" >&2; exit 1 ;;
\?) echo "Error: unknown -$OPTARG" >&2; exit 1 ;;
esac
done
shift $((OPTIND - 1))
echo "verbose=$VERBOSE quiet=$QUIET count=$COUNT"Gestionar el separador de dos guiones
Los comandos de Unix aceptan -- (dos guiones) como señal explícita para detener el procesamiento de opciones. Todo lo que aparece después de -- se trata como un argumento posicional, aunque parezca un indicador.
getopts se detiene automáticamente cuando encuentra --. Después de shift $((OPTIND - 1)), los dos guiones desaparecen y $@ contiene únicamente los operandos.
Esto es importante para los scripts que operan con nombres de archivo que podrían comenzar por un guion, por ejemplo:
myscript.sh -v -- -strangefile.txt#!/usr/bin/env bash
# Demonstrate -- separator
# Run as: bash script.sh -v -- file1.txt -oddname.txt
VERBOSE=0
while getopts ':v' opt; do
case "$opt" in
v) VERBOSE=1 ;;
\?) echo "Unknown option -$OPTARG" >&2; exit 1 ;;
esac
done
shift $((OPTIND - 1)) # removes -v and the '--' separator
echo "Verbose: $VERBOSE"
echo "Files to process:"
for f in "$@"; do
echo " -> $f"
doneEnvolver getopts en una función de biblioteca
En los scripts modulares, puede encapsular getopts dentro de una función parse_args() que establezca variables globales (o variables nameref). Esto mantiene main() limpio y permite cargar el analizador desde otros scripts.
Reglas principales de este patrón:
- Declare las variables de las opciones antes de llamar a la función
- Use variables
globalo pase los valores mediante nameref (declare -n) - Devuelva un código de salida distinto de cero si la entrada no es válida, para que
mainpueda reaccionar
#!/usr/bin/env bash
# Global option variables
VERBOSE=0; OUTPUT=''; COUNT=1
parse_args() {
local opt
while getopts ':vn:o:h' opt; do
case "$opt" in
v) VERBOSE=1 ;;
n) COUNT="$OPTARG" ;;
o) OUTPUT="$OPTARG" ;;
h) echo "Usage: $(basename "$0") [-v] [-n N] [-o FILE]"; exit 0 ;;
:) echo "Error: -$OPTARG needs a value" >&2; return 1 ;;
\?) echo "Error: unknown option -$OPTARG" >&2; return 1 ;;
esac
done
shift $((OPTIND - 1))
ARGS=("$@") # leftover positional args stored in array
}
main() {
parse_args "$@" || exit 1
echo "verbose=$VERBOSE count=$COUNT output=${OUTPUT:--} args=${ARGS[*]}"
}
main "$@"Ejemplo completo del mundo real: un archivador de registros
A continuación se muestra un script completo del mundo real que utiliza todo lo visto en esta lección: un optstring con argumentos obligatorios, el modo de error silencioso, una función de uso, valores predeterminados, validación y el desplazamiento de OPTIND.
Estudie la estructura: es la plantilla que debe seguir en cualquier script que escriba y que necesite una interfaz CLI.
#!/usr/bin/env bash
# archive_logs.sh — compress and move logs older than N days
set -euo pipefail
DESTDIR='/tmp/log_archive'
DAYS=30
VERBOSE=0
usage() {
cat >&2 <<EOF
Usage: $(basename "$0") [-v] [-d DAYS] [-o DIR] SOURCE_DIR
-d DAYS Archive logs older than DAYS (default: 30)
-o DIR Destination directory (default: /tmp/log_archive)
-v Verbose output
-h Show this help
EOF
exit "${1:-0}"
}
while getopts ':d:o:vh' opt; do
case "$opt" in
d) DAYS="$OPTARG" ;;
o) DESTDIR="$OPTARG" ;;
v) VERBOSE=1 ;;
h) usage 0 ;;
:) echo "Error: -$OPTARG requires a value" >&2; usage 1 ;;
\?) echo "Error: unknown option -$OPTARG" >&2; usage 1 ;;
esac
done
shift $((OPTIND - 1))
# Validation
[[ $# -lt 1 ]] && { echo "Error: SOURCE_DIR is required" >&2; usage 1; }
[[ "$DAYS" =~ ^[0-9]+$ ]] || { echo "Error: DAYS must be numeric" >&2; exit 1; }
SOURCE="$1"
[[ -d "$SOURCE" ]] || { echo "Error: '$SOURCE' is not a directory" >&2; exit 1; }
mkdir -p "$DESTDIR"
[[ $VERBOSE -eq 1 ]] && echo "Archiving logs older than $DAYS days from $SOURCE to $DESTDIR"
find "$SOURCE" -name '*.log' -mtime "+$DAYS" -print | while read -r f; do
gzip -c "$f" > "$DESTDIR/$(basename "$f").gz"
[[ $VERBOSE -eq 1 ]] && echo " archived: $f"
done
echo "Done."Comprobación rápida: el optstring de getopts
Lea la siguiente llamada a getopts y elija la descripción correcta de su comportamiento:
while getopts ':f:vq' opt; doRepaso de la lección: dominar getopts
Ha aprendido a crear interfaces profesionales de línea de comandos en Bash mediante getopts. Estos son los puntos clave:
- Sintaxis de optstring — las letras sin dos puntos son indicadores booleanos; los dos puntos después de una letra indican que requiere un argumento; los dos puntos iniciales activan el modo de error silencioso.
- OPTARG — contiene automáticamente el valor del argumento de las opciones que requieren uno.
- OPTIND — use
shift $((OPTIND - 1))después del bucle para dejar disponibles los parámetros posicionales restantes en$@. - Modo de error silencioso — preferido en producción; gestione usted mismo los casos
:(argumento ausente) y\?(opción desconocida) para tener un control total. - Función usage() — escríbala siempre; muestre el mensaje en stderr, salga con 0 para
-hy con 1 para los errores. - Indicadores combinados — getopts gestiona automáticamente
-vqy-n5sin código adicional. - Patrón modular — envuelva getopts en una función
parse_args()para crear scripts limpios y reutilizables.
Dominar getopts transforma sus scripts de herramientas de propósito único en programas CLI fiables y fáciles de usar que siguen las convenciones de Unix.
Preguntas frecuentes
¿La lección «Análisis de flags y argumentos con getopts» es gratis?
Sí — el texto completo de «Análisis de flags y argumentos con getopts» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Linux Command Line & Bash Scripting Mastery, actualiza a CoddyKit PRO. El curso de Linux Command Line & Bash Scripting Mastery incluye 4 lecciones en total.
¿Qué aprenderé en «Análisis de flags y argumentos con getopts»?
Implemente interfaces de línea de comandos profesionales con getopts para opciones cortas, argumentos obligatorios y mensajes de uso. Practicas Linux Command Line & Bash Scripting Mastery con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar Linux Command Line & Bash Scripting Mastery?
No se requiere experiencia previa. Linux Command Line & Bash Scripting Mastery en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 3 de 4.
¿Cuánto tiempo toma la lección «Análisis de flags y argumentos con getopts»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de Linux Command Line & Bash Scripting Mastery?
Sí. Cada lección de Linux Command Line & Bash Scripting Mastery incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.
Todas las lecciones de este curso
- Diseño de funciones con ámbito local y códigos de retorno
- Creación y carga de bibliotecas Bash reutilizables
- Análisis de flags y argumentos con getopts
- Paso de matrices y mapas asociativos entre funciones