ejemplos - Uso de getopts dentro de una función de Bash
awk unix (3)
Aquí hay un ejemplo simple del uso de getopts
dentro de la función de shell:
#!/usr/bin/env bash
t() {
local OPTIND
getopts "a:" OPTION
echo Input: $*, OPTION: $OPTION, OPTARG: $OPTARG
}
t "$@"
t -a foo
Salida:
$ ./test.sh -a bc
Input: -a bc, OPTION: a, OPTARG: bc
Input: -a foo, OPTION: a, OPTARG: foo
Como señaló @Adrian , local OPTIND
(u OPTIND=1
) debe establecerse porque Shell no restablece automáticamente OPTIND
entre múltiples llamadas a getopts
( man bash
).
La sintaxis getopts
para getopts
es:
getopts OPTSTRING VARNAME [ARGS...]
y por defecto, no especificar argumentos equivale a llamarlo explícitamente con "$ @" que es: getopts "a:" opts "$@"
.
En caso de problemas, estas son las variables usadas para getopts
para verificar:
-
OPTIND
: el índice al siguiente argumento que se procesará. -
OPTARG
- variable se establece en cualquier argumento para una opción encontrada porgetopts
, -
OPTERR
(no POSIX): establezca en 0 o 1 para indicar si Bash debería mostrar los mensajes de error generados por losgetopts
.
Además, ver: Pequeño tutorial getopts en The Bash Hackers Wiki
Me gustaría usar getopts
dentro de una función que he definido en mi .bash_profile. La idea es que me gustaría pasar algunas banderas a esta función para alterar su comportamiento.
Aquí está el código:
function t() {
echo $*
getopts "a:" OPTION
echo $OPTION
echo $OPTARG
}
Cuando lo invoco así:
t -a bc
Obtengo esta salida:
-a bc
?
¿Qué pasa? Me gustaría obtener el valor bc
sin cambiar y analizar manualmente. ¿Cómo uso getopts
correctamente dentro de una función?
EDITAR: corrigió mi fragmento de código para probar $ OPTARG, en vano
EDIT # 2: OK resulta que el código está bien, mi shell estaba de alguna manera en mal estado. Abrir una nueva ventana lo resolvió. El valor de arg era de hecho en $ OPTARG.
Como señala @Ansgar, el argumento para su opción se almacena en ${OPTARG}
, pero esto no es lo único que hay que tener en cuenta al usar getopts
dentro de una función. También debe asegurarse de que ${OPTIND}
sea local para la función, ya sea desvinculándola o declarándola local
, de lo contrario, encontrará un comportamiento inesperado al invocar la función varias veces.
t.sh
:
#!/bin/bash
foo()
{
foo_usage() { echo "foo: [-a <arg>]" 1>&2; exit; }
local OPTIND o a
while getopts ":a:" o; do
case "${o}" in
a)
a="${OPTARG}"
;;
*)
foo_usage
;;
esac
done
shift $((OPTIND-1))
echo "a: [${a}], non-option arguments: $*"
}
foo
foo -a bc bar quux
foo -x
Ejecución de ejemplo:
$ ./t.sh
a: [], non-option arguments:
a: [bc], non-option arguments: bar quux
foo: [-a <arg>]
Si comenta # local OPTIND
, esto es lo que obtiene en su lugar:
$ ./t.sh
a: [], non-option arguments:
a: [bc], non-option arguments: bar quux
a: [bc], non-option arguments:
Aparte de eso, su uso es el mismo que cuando se usa fuera de una función.
El argumento está almacenado en $OPTARG
.
function t() {
echo $*
getopts "a:" OPTION
echo $OPTION
echo $OPTARG
}
Salida:
$ t -a bc
-a bc
a
bc