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 getoptssería la forma preferida en términos de portabilidad, pero AFAIK no admite opciones largas.
getoptadmite 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
getoptvsgetoptsparece ser un problema religioso. En cuanto a los argumentosgetopten contra en las preguntas frecuentes de Bash :"
getoptno se pueden manejar cadenas de argumentos vacías" parece referirse a un problema conocido con argumentos opcionales , que parece quegetoptsno es compatible en absoluto (al menos al leerhelp getoptsBash 4.2.24). Deman getopt:No sé de dónde
getoptviene 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
getoptcita aquí es específica de Linux. Tenga en cuenta quegetoptno 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.getoptes un comando tradicional que proviene del Sistema V mucho antes de que se lanzara Linux.getoptnunca fue estandarizado. Ninguno de POSIX, Unix o Linux (LSB) nunca estandarizó elgetoptcomando.getoptsse 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
perly suGetopt::Longmódulo, que debería estar disponible en la mayoría de los Unices hoy en día, ya sea escribiendo todo el scriptperlo simplemente llamando a perl solo para analizar la opción y alimentar la información extraída al shell. Algo como:Vea
perldoc Getopt::Longqué 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
getopten sistemas que lo admitan y usar una alternativa para sistemas que no lo admiten.Por ejemplo,
pure-getoptse implementa en Bash puro para ser un reemplazo directo de GNUgetopt.fuente