Quiero llamar al myscript
archivo de esta manera:
$ ./myscript -s 45 -p any_string
o
$ ./myscript -h #should display help
$ ./myscript #should display help
Mis requisitos son:
getopt
aquí para obtener los argumentos de entrada- compruebe que
-s
existe, si no devuelve un error - compruebe que el valor después de
-s
es 45 o 90 - compruebe que
-p
existe y hay una cadena de entrada después - si el usuario ingresa
./myscript -h
o simplemente./myscript
muestra ayuda
Intenté hasta ahora este código:
#!/bin/bash
while getopts "h:s:" arg; do
case $arg in
h)
echo "usage"
;;
s)
strength=$OPTARG
echo $strength
;;
esac
done
Pero con ese código obtengo errores. ¿Cómo hacerlo con Bash y getopt
?
-s
, lo convierten en un argumento posicional:./myscript 45 anystring
.$./myscript -s 45 -p any_string
-p
realidad es una opción (es decir, su programa puede continuar si no está presente). En este caso./myscript 45 -p any_string
,. (Creo quegetopt
puede manejar opciones mixtas y argumentos posicionales, mientras que elbash
comando integradogetopts
requiere que todos los argumentos posicionales para ser colocado después de las opciones.)Respuestas:
Ejecuciones de ejemplo:
fuente
usage()
Realmente debería devolver 1?-h
él, debería regresar0
, al presionar un indicador no existente, debería regresar>0
(por simplicidad, no diferenciaba entre esos casos y nadie lo obliga a imprimir el texto de uso en el último caso) . Sin!= 0
embargo, he visto programas que siempre regresan , incluso-h/--help
. ¿Tal vez debería actualizar el fragmento en caso de que la gente use esto como repetitivo (espero que no)?getopts
') diseño, no existe tal cosa como "argumentos opcionales" congetopts
. El analizador simplemente no puede saber si el siguiente token es un argumento para la opción actual o una opción en sí misma, ya que-p
podría ser el valor deseado. Usted puede cortar alrededor de este si es absolutamente sabe que un parámetro de opción no puede verse como otra opción válida, sí, pero se podría decir que hay una razón argumentos opcionales no están definidos en POSIX.bash
lexer a identificar variables. En muchos casos son innecesarios y el hecho de que siempre los use es solo una cuestión de estilo de codificación personal. Para mí, es más fácil (y más bonito) usarlos siempre en lugar de recordar las reglas de análisis con respecto a la ambigüedad. Más o menos lo mismo por qué uno escribiría enif (foo) { bar; }
lugar deif (foo) bar;
un lenguaje de estilo C (estética y / o evitar errores tontos).El problema con el código original es que:
h:
espera el parámetro donde no debería, así que cámbielo a soloh
(sin dos puntos)-p any_string
, debe agregarp:
a la lista de argumentosBásicamente
:
después de que la opción significa que requiere el argumento.La sintaxis básica de
getopts
es (ver:)man bash
:dónde:
OPTSTRING
es una cadena con una lista de argumentos esperados,h
- Verifique la opción-h
sin parámetros; da error en opciones no compatibles;h:
- verifique la opción-h
con el parámetro; da errores en opciones no compatibles;abc
- verificación de opciones-a
,-b
,-c
; da errores en opciones no compatibles;:abc
- verificación de opciones-a
,-b
,-c
; silencia los errores en opciones no compatibles;Notas: En otras palabras, los dos puntos delante de las opciones le permiten manejar los errores en su código. La variable contendrá
?
en el caso de una opción no admitida,:
en el caso de un valor perdido.OPTARG
- se establece en el valor del argumento actual,OPTERR
- indica si Bash debería mostrar mensajes de error.Entonces el código puede ser:
Ejemplo de uso:
Ver: Pequeño tutorial de getopts en Bash Hackers Wiki
fuente
usage() { echo "$0 usage:" && grep "[[:space:]].)\ #" $0 | sed 's/#//' | sed -r 's/([a-z])\)/-\1/'; exit 0; }
. Solo representa un solo carácter de espacio en blanco antes de la opción de letra, elimina el # del comentario y antepone un '-' antes de la opción de letra, lo que lo hace más claro para el comando.:
correcto hasta que vi estas notas. Necesitamos agregar un:
a las opciones donde esperamos un argumento.Utilizar
getopt
¿Por qué getopt?
Analizar argumentos elaborados de la línea de comandos para evitar confusiones y aclarar las opciones que estamos analizando para que el lector de los comandos pueda entender lo que está sucediendo.
¿Qué es getopt?
getopt
se utiliza para dividir (analizar) las opciones en las líneas de comando para facilitar el análisis mediante procedimientos de shell y para buscar opciones legales. Utiliza lasgetopt(3)
rutinas GNU para hacer esto.getopt
puede tener los siguientes tipos de opciones.Nota: En este documento, durante la explicación de la sintaxis:
¿CÓMO UTILIZAR
getopt
?Sintaxis: primera forma
Ejemplos:
Aquí h, v, t son las opciones y -h -v -t es cómo se deben dar las opciones en la línea de comandos.
En el parámetro opcional, el valor no puede tener separación de espacios en blanco con la opción. Entonces, en el ejemplo "-t123", -t es la opción 123 es el valor.
Sintaxis: Segunda forma
Aquí después de getopt se divide en cinco partes
Ejemplos
Sintaxis: Tercera forma
Aquí después de getopt se divide en cinco partes
Ejemplos
GETOPT_OPTIONS
getopt_options cambia la forma en que se analizan los parámetros de la línea de comandos.
A continuación se muestran algunas de las opciones getopt
Opción: -l o --longoptions
Por ejemplo,
--name=Karthik
es una opción larga enviada en línea de comando. En getopt, el uso de opciones largas es comoComo nombre: se especifica, la opción debe contener un valor
Opción: -a o --alternativa
Ejemplo, en lugar de
--name=Karthik
usted podría usar solo-name=Karthik
Un ejemplo completo de script con el código:
Ejecutando este archivo de script:
fuente
El ejemplo empaquetado con
getopt
(mi distribución lo puso/usr/share/getopt/getopt-parse.bash
) parece que cubre todos sus casos:fuente
Sé que esto ya está respondido, pero para el registro y para cualquier persona con los mismos requisitos que yo, decidí publicar esta respuesta relacionada. El código está inundado de comentarios para explicar el código.
Respuesta actualizada:
Guarde el archivo como
getopt.sh
:Entonces puedes usarlo así:
Vieja respuesta:
Hace poco necesitaba usar un enfoque genérico. Encontré esta solución:
No probé esto más o menos, así que podría tener algunos errores allí.
fuente
getopts
una función, agreguelocal OPTIND OPTARG
a la funcióngetopts
POSIX 7 ejemplo
También vale la pena consultar el ejemplo del estándar: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/getopts.html
Y luego podemos probarlo:
Probado en Ubuntu 17.10,
sh
es el guión 0.5.8.fuente
"getops" y "getopt" son muy limitados. Si bien se sugiere que "getopt" no se use en absoluto, ofrece opciones largas. Donde como "getopts" solo permite opciones de caracteres individuales como "-a" "-b". Hay algunas desventajas más al usar cualquiera de los dos.
Así que escribí un pequeño script que reemplaza "getopts" y "getopt". Es un comienzo, probablemente podría mejorarse mucho.
Actualización 08-04-2020 : he agregado soporte para guiones, por ejemplo, "--package-name".
fuente