Actualmente estoy escribiendo un script Bash que tiene los siguientes requisitos:
- debería ejecutarse en una amplia variedad de plataformas Unix / Linux
- debería admitir opciones cortas y largas (GNU)
Sé que getopts
sería la forma preferida en términos de portabilidad, pero AFAIK no admite opciones largas.
getopt
admite opciones largas, pero BashGuide recomienda enfáticamente que no lo haga :
Nunca use getopt (1). getopt no puede manejar cadenas de argumentos vacías o argumentos con espacios en blanco incrustados. Por favor, olvide que alguna vez existió.
Por lo tanto, todavía existe la opción de análisis manual. Esto es propenso a errores, produce bastante código repetitivo y necesito manejar los errores por mí mismo (supongo getopt(s)
que los manejo de errores por sí mismos).
Entonces, ¿cuál sería la opción preferida en este caso?
bash
shell-script
options
user-interface
getopts
método de ayuda
fuente
fuente
Respuestas:
Si tiene que ser portátil para una gama de Unices, debería atenerse a POSIX sh. Y AFAIU allí no tiene más remedio que manejar el argumento a mano.
fuente
getopt
vsgetopts
parece ser un problema religioso. En cuanto a los argumentosgetopt
en contra en las preguntas frecuentes de Bash :"
getopt
no se pueden manejar cadenas de argumentos vacías" parece referirse a un problema conocido con argumentos opcionales , que parece quegetopts
no es compatible en absoluto (al menos al leerhelp getopts
Bash 4.2.24). Deman getopt
:No sé de dónde
getopt
viene el " no puede manejar [...] argumentos con espacios en blanco incrustados", pero probémoslo:test.sh:
correr:
Me parece un jaque y un compañero, pero estoy seguro de que alguien me mostrará cómo entendí mal la oración. Por supuesto, el problema de la portabilidad sigue en pie; tendrá que decidir cuánto tiempo vale la pena invertir en plataformas con un Bash antiguo o sin Bash disponible. Mi propio consejo es utilizar las pautas de YAGNI y KISS : desarrolle solo para aquellas plataformas específicas que sabe que se utilizarán. La portabilidad del código Shell generalmente llega al 100% a medida que el tiempo de desarrollo llega al infinito.
fuente
getopt
cita aquí es específica de Linux. Tenga en cuenta quegetopt
no forma partebash
, ni siquiera es una utilidad GNU y en Linux se envía con el paquete util-linux.getopt
, solo Linux AFAIK viene con una que admite opciones largas o espacios en blanco en los argumentos. Los otros solo admitirían la sintaxis del Sistema V.getopt
es un comando tradicional que proviene del Sistema V mucho antes de que se lanzara Linux.getopt
nunca fue estandarizado. Ninguno de POSIX, Unix o Linux (LSB) nunca estandarizó elgetopt
comando.getopts
se especifica en los tres pero sin soporte para opciones largas.getopt
. Es el sabor de linux-utils como lo indica @ StéphaneChazelas. Tiene opciones heredadas que deshabilitarán la sintaxis descrita anteriormente, en particular la página de manual dice "GETOPT_COMPATIBLE obliga a getopt a usar el primer formato de llamada como se especifica en la SINOPSIS". Sin embargo, si puede esperar que los sistemas de destino tengan este paquete instalado, este es el camino a seguir, ya que el getopt original es horrible y el getopt de Bash es muy limitadoExiste este getopts_long escrito como una función de shell POSIX que puede incrustar dentro de su script.
Tenga en cuenta que Linux
getopt
(fromutil-linux
) funciona correctamente cuando no está en modo tradicional y admite opciones largas, pero probablemente no sea una opción para usted si necesita ser portátil a otros Unices.Las versiones recientes de ksh93 (
getopts
) y zsh (zparseopts
) tienen soporte incorporado para analizar opciones largas que podrían ser una opción para usted, ya que están disponibles para la mayoría de los Unices (aunque a menudo no están instaladas de manera predeterminada).Otra opción sería usar
perl
y suGetopt::Long
módulo, que debería estar disponible en la mayoría de los Unices hoy en día, ya sea escribiendo todo el scriptperl
o simplemente llamando a perl solo para analizar la opción y alimentar la información extraída al shell. Algo como:Vea
perldoc Getopt::Long
qué puede hacer y en qué se diferencia de otros analizadores de opciones.fuente
Cada discusión sobre este asunto resalta la opción de escribir el código de análisis manualmente, solo entonces puede estar seguro de la funcionalidad y portabilidad. Le aconsejo que no escriba código que pueda haber generado y regenerado mediante generadores de código abierto fáciles de usar. Use Argbash , que ha sido diseñado para proporcionar la respuesta definitiva a su problema. Es un generador de código bien documentado disponible como una aplicación de línea de comandos , en línea o como una imagen de Docker .
Aconsejo contra las bibliotecas de bash, algunas de ellas usan
getopt
(lo que hace que sea bastante inportable) y es difícil agrupar un blob de shell ilegible gigantesco con su script.fuente
Puede usarlo
getopt
en sistemas que lo admitan y usar una alternativa para sistemas que no lo admiten.Por ejemplo,
pure-getopt
se implementa en Bash puro para ser un reemplazo directo de GNUgetopt
.fuente