0Pricing
Linux Command Line & Bash Scripting Mastery · Lección

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 OPTIND y OPTARG

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
done

Definir un optstring

El optstring es una declaración compacta del contrato de su CLI. Cada carácter representa un indicador aceptado.

  • 'abc' — acepta -a, -b y -c (sin argumentos)
  • 'a:bc' — -a requiere un argumento; -b y -c no 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 / --help y con el código 1 para un uso no válido
  • Llamar a usage 1 en las rutas de error y a usage 0 en 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!"
done

Combinar 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 -q equivale a -vq
  • -n 5 -v equivale a -n5 -v o -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"
done

Envolver 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 global o 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 main pueda 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; do

Repaso 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 -h y con 1 para los errores.
  • Indicadores combinados — getopts gestiona automáticamente -vq y -n5 sin 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

  1. Diseño de funciones con ámbito local y códigos de retorno
  2. Creación y carga de bibliotecas Bash reutilizables
  3. Análisis de flags y argumentos con getopts
  4. Paso de matrices y mapas asociativos entre funciones
← Volver a Linux Command Line & Bash Scripting Mastery