Acabo de descubrir que getopt
no es multiplataforma (en particular para FreeBSD y Linux). ¿Cuál es la mejor solución para este problema?Getopt multiplataforma para un script de shell
Respuesta
Uso getopts
(con una "s").
Según Bash FAQ 35:
A menos que sea la versión de util-linux, y utiliza su modo avanzado, no utilice nunca getopt (1). getopt no puede manejar cadenas de argumentos vacíos, o argumentos con espacios en blanco incrustados. Por favor, olvide que alguna vez existió.
El shell POSIX (y otros) ofrecen getopts que es seguro de usar en su lugar.
Uso el mnemotécnico "S" para Shell, getopt "S" está integrado en BASH –
@Dennis Williamson Actualice su respuesta: Según la entrada de preguntas frecuentes (actualizada): ** A menos que sea la versión de util-linux, y usted use su modo avanzado, nunca use getopt (1). ... ** – Florian
@Florian: actualizado. Gracias. –
La sintaxis básica para getopt
es multiplataforma.
getopt vi: -v -i 100 file
Existen esencialmente dos versiones del comando getopt
: la versión original y la versión mejorada de GNU. La versión mejorada de GNU es retrocompatible con la versión original, por lo que si solo utiliza las características de la versión original, funcionará con ambas.
Detectar la versión de getopt está disponible
Puede detectar qué versiones y utiliza las características mejoradas si la versión de GNU mejorada está disponible, y se limita a las características originales si la versión de GNU mejorado es no disponible. La versión mejorada tiene una opción -T
para probar qué versión está disponible.
getopt -T > /dev/null
if [ $? -eq 4 ]; then
# GNU enhanced getopt is available
set -- `getopt --long help,output:,version --options ho:v -- "[email protected]"`
else
# Original getopt is available
set -- `getopt ho:v "[email protected]"`
fi
Considere el uso de comandos shell integrado getopts
(con una "s") en lugar, porque es más portátil. Sin embargo, getopts
no admite opciones largas (por ejemplo, --help
).
Si te gusta las opciones largas, utilizar getopt
y el uso de la prueba anterior para ver si la versión mejorada de GNU getopt
está disponible o no. Si la versión mejorada no está disponible, la secuencia de comandos puede degradarse con gracia utilizando la versión original de getopt
(sin soporte para nombres largos de opción y sin soporte de espacio en blanco) o usando getopts
(sin soporte para nombres de opción largos).
Usando GNU getopt mejorado adecuadamente
Obtener la versión mejorada de GNU para procesar argumentos con espacios en blanco correctamente es difícil. Así es como se hace:
ARGS=`getopt --long help,output:,verbose --options ho:v -- "[email protected]"`
if [ $? -ne 0 ]; then
echo "Usage error (use -h for help)" >&2
exit 2
fi
eval set -- $ARGS
# Parameters are now sorted: options appear first, followed by --, then arguments
# e.g. entering: "foo bar" -o abc baz -v
# produces: -o 'abc' -v -- 'foo bar' 'baz'
El secreto es usar "[email protected]"
donde las comillas dobles son muy importantes (en la línea 1), y para el eval
establece de comandos (en la línea 6).
Para detectar y manejar los errores provocados por getopt
, la llamada a getopt
se realiza por separado desde eval
con los dos vinculados por la variable ARGS.
ejemplo de trabajo completa
PROG=`basename $0`
getopt -T > /dev/null
if [ $? -eq 4 ]; then
# GNU enhanced getopt is available
ARGS=`getopt --name "$PROG" --long help,output:,verbose --options ho:v -- "[email protected]"`
else
# Original getopt is available (no long option names, no whitespace, no sorting)
ARGS=`getopt ho:v "[email protected]"`
fi
if [ $? -ne 0 ]; then
echo "$PROG: usage error (use -h for help)" >&2
exit 2
fi
eval set -- $ARGS
while [ $# -gt 0 ]; do
case "$1" in
-h | --help) HELP=yes;;
-o | --output) OUTFILE="$2"; shift;;
-v | --verbose) VERBOSE=yes;;
--) shift; break;; # end of options
esac
shift
done
if [ $# -gt 0 ]; then
# Remaining parameters can be processed
for ARG in "[email protected]"; do
echo "$PROG: argument: $ARG"
done
fi
echo "$PROG: verbose: $VERBOSE"
echo "$PROG: output: $OUTFILE"
echo "$PROG: help: $HELP"
Este ejemplo se puede descargar desde https://gist.github.com/hoylen/6607180
La tabla de comparación en Wikipedia's entry on getopts comparan las diferentes características.
Sí, 'getopts' (con una s) es otra opción. Los puristas de la portabilidad preferirían aún el getopt, ya que los getopts no estaban disponibles en las antiguas conchas de Bourne antes de 1986, pero esa es una razón de peso porque la mayoría de las conchas modernas son compatibles. Una mejor razón es hacer que sea más fácil aprovechar el complemento mejorado de GNU si está disponible. El getopt mejorado de GNU permite mezclar operandos con opciones y admite nombres de opciones largos (ambas características que getopts no admite - vea [tabla de comparación] [1]). – Hoylen
¿Por qué imprime un '--' vacío cuando ejecuto' eval set - $ ARGS'? Es muy irritante – Hindol
La función getopts Bash orden interna se puede utilizar para analizar las opciones cortas y largas de forma portátil, ver:
Using getopts in bash shell script to get long and short command line options
- 1. Shell script para detener un programa java
- 2. Análisis del argumento del script de Shell
- 3. cómo usar un script de shell para supervisar un programa?
- 4. Prueba de un script de shell bash
- 5. Prueba de script Shell
- 6. Pretty-print para script de shell
- 7. script de shell: if
- 8. ¿Cómo hacer un script de shell global?
- 9. Telnet dentro de un script de shell
- 10. Biblioteca GetOpt para C#
- 11. Crear un script de shell para ejecutar el programa Java
- 12. ¿Qué significa $ @ en un script de shell?
- 13. plantillas de script de shell
- 14. Shell script "para" la sintaxis del bucle
- 15. Shell script para ejecutar procesos múltiples
- 16. Shell script shebang para ruta desconocida
- 17. música con script de shell
- 18. de clasificación en shell script
- 19. shell script + números de suma
- 20. carácter \ r en shell script
- 21. Incrustar un ejecutable binario en un script de shell
- 22. ¿Cómo ejecuto un editor desde un script de shell?
- 23. Escribir un script de Fish Shell con un argumento opcional
- 24. Cómo ejecutar un comando de shell desde un script php
- 25. ¿Cómo imprimir el resultado del script de shell en CMake?
- 26. ¿Cómo puedo redireccionar stdin desde un script de shell a un comando en el script de shell?
- 27. shell script y SQL resultados
- 28. shell script salida al portapapeles
- 29. Shell script generando un proceso después de un retraso
- 30. Ejecutar un script de shell con un botón html
Si ha iniciado a cabo usando getopt GNU con largas opciones, etc., y están buscando para hacer su código existente portátil con el menor número de cambios posible, entonces puede encontrar útil http://stackoverflow.com/a/37087374/324105. – phils