Quiero llamar al myscriptarchivo de esta manera:
$ ./myscript -s 45 -p any_string
o
$ ./myscript -h #should display help
$ ./myscript #should display help
Mis requisitos son:
getoptaquí para obtener los argumentos de entrada- compruebe que
-sexiste, si no devuelve un error - compruebe que el valor después de
-ses 45 o 90 - compruebe que
-pexiste y hay una cadena de entrada después - si el usuario ingresa
./myscript -ho simplemente./myscriptmuestra 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-prealidad es una opción (es decir, su programa puede continuar si no está presente). En este caso./myscript 45 -p any_string,. (Creo quegetoptpuede manejar opciones mixtas y argumentos posicionales, mientras que elbashcomando integradogetoptsrequiere 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!= 0embargo, 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-ppodrí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.bashlexer 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
getoptses (ver:)man bash:dónde:
OPTSTRINGes una cadena con una lista de argumentos esperados,h- Verifique la opción-hsin parámetros; da error en opciones no compatibles;h:- verifique la opción-hcon 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?
getoptse 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.getoptpuede 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=Karthikes 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=Karthikusted podría usar solo-name=KarthikUn 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
getoptsuna función, agreguelocal OPTIND OPTARGa la funcióngetoptsPOSIX 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,
shes 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