Al desarrollar scripts Bash, frecuentemente se necesita o desea poder obtener ciertos parámetros en forma de argumentos de línea de comandos, es decir, al momento de invocar el script. Esta es una tarea sencilla si nuestro script necesita un único parámetro por línea de comandos. Sin embargo, si deseamos soportar cualquier número de argumentos y opciones que requieran o no un parámetro adicional, las cosas se complican. Especialmente si la mayoría de los parámetro son opcionales y deseamos soportar cualquier orden.

Este artículo demuestra una técnica simple para recuperar opciones y parámetros como argumentos de línea de comandos al desarrollar scripts Bash.

Bash posee ciertas variables especiales para el manejo de argumentos de línea de comandos:

  • $#: cantidad de argumentos.
  • $i: argumento en la posición i, siendo éste un número entero desde 0 hasta infinito (por ejemplo: $3 retorna el argumento en la posición 3).
  • $* y $@: expanden todos los argumentos a partir de la posición 1.

Además se dispone comando shift, el cual descarta parámetros desde la primera posición.

Para entender cómo es posible aprovechar estas variables, veamos directamente un ejemplo:

#!/bin/bash

# variables internas

ARG1=""
ARG2=""
OPT1="no"
OPT2="no"
HELP="no"

# procesar argumentos

while [[ $# -gt 1 ]]; do

  # mientras queden argumentos por procesar ($# > 1)

  CLAVE="$1"

  case CLAVE in
    -a|--arg1)
    ARG1="$2"
    shift # descartar argumento
    ;;
    -b|--arg2)
    ARG2="$2"
    shift # descartar argumento
    ;;
    -o|--option1)
    OPT1="yes"
    ;;
    -p|--option2)
    OPT2="yes"
    ;;
    -h|--help)
    HELP="yes"
    ;;
    *)
    # opción desconocida
    ;;
  esac
  shift # descartar argumento o parámetro
done

# continuar según los valores de las variables internas...

Lo que hace este mecanismo es simple: mientras queden argumentos por procesar, los interpreta y actualiza variables internas. Por cada opción se define una o más variables internas. Las opciones -a y -b toman un parámetro, cuyo valor se almacena en las variables ARG1 y ARG2 respectivamente. Las opciones -o, -p y -h son simples, y sólo se utilizan para alterar el funcionamiento del script. Cada una cuenta con su respectiva variable interna, que indica si está presente o no en la línea de comandos.

Además se soporta el uso de opciones "largas" a través del operador | (or). Por ejemplo, es posible utilizar tanto -a "hola que tal" como --arg1 "hola que tal".

Recordar que el primer argumento ($0) es siempre el nombre del ejecutable en los sistemas operativos de la familia Unix. Es por ello que se controla (luego de hacer shift) que la cantidad de argumentos sea mayor a 1.

De esta forma, el script (denominado miscript.bash) se puede invocar de la siguiente manera:

$ ./miscript.bash -a valor1 -b "otro valor" -o -p -h

Generalmente, las opciones simples (que no identifican un parámetro sino que alteran el comportamiento o funcionamiento del script) son opcionales, valga la redundancia. Las opciones compuestas (que identifican y requieren un parámetro adicional) pueden ser o no opcionales, dependiendo de cada programa. Si necesitamos que una opción compuesta sea obligatoria, sólo hace falta verificar el valor de su correspondiente variable interna al salir del bucle.

Este esquema permite entonces cualquier orden en las opciones, por ejemplo:

$ ./miscript.bash --option1 -b "otro valor" -p -a valor1

La única desventaja es que no soporta agrupar opciones en un único símbolo -, por ejemplo:

$ ./miscript.bash -oph -a valor1

Para ello se requiere un procesamiento de argumentos más complejo y robusto. Por supuesto, este artículo apunta a proveer una solución simple y rápida que permita recuperar un número aleatorio de argumentos de línea de comandos en cualquier orden.

Referencias


Tal vez pueda interesarte


Compartí este artículo