Deseo que se invoquen formas largas y cortas de opciones de línea de comando utilizando mi script de shell.
Sé que getopts
se puede usar, pero como en Perl, no he podido hacer lo mismo con Shell.
Alguna idea sobre cómo se puede hacer esto, para que pueda usar opciones como:
./shell.sh --copyfile abc.pl /tmp/
./shell.sh -c abc.pl /tmp/
En lo anterior, ambos comandos significan lo mismo para mi shell, pero usando getopts
, ¿no he podido implementarlos?
bash
command-line-arguments
getopt
getopts
gagneet
fuente
fuente
Respuestas:
Hay tres implementaciones que pueden considerarse:
Bash incorporado
getopts
. Esto no admite nombres largos de opciones con el prefijo de doble guión. Solo admite opciones de un solo carácter.Implementación BSD UNIX del
getopt
comando independiente (que es lo que usa MacOS). Esto tampoco admite opciones largas.Implementación GNU de autónomo
getopt
. GNUgetopt(3)
(utilizado por la línea de comandosgetopt(1)
en Linux) admite el análisis de opciones largas.Algunas otras respuestas muestran una solución para usar bash builtin
getopts
para imitar opciones largas. Esa solución en realidad hace una opción corta cuyo carácter es "-". Entonces obtienes "-" como la bandera. Luego, todo lo que sigue se convierte en OPTARG, y prueba el OPTARG con un anidadocase
.Esto es inteligente, pero viene con advertencias:
getopts
no se puede hacer cumplir la especificación opt. No puede devolver errores si el usuario proporciona una opción no válida. Debe realizar su propia comprobación de errores mientras analiza OPTARG.Por lo tanto, si bien es posible escribir más código para evitar la falta de soporte para opciones largas, esto es mucho más trabajo y anula parcialmente el propósito de usar un analizador getopt para simplificar su código.
fuente
getopt
ygetopts
son diferentes bestias, y las personas parecen tener un poco de incomprensión de lo que hacen.getopts
es un comando incorporadobash
para procesar las opciones de la línea de comandos en un bucle y asignar cada opción y valor encontrados a su vez a las variables incorporadas, para que pueda procesarlas aún más.getopt
, sin embargo, es un programa de utilidad externo, y en realidad no procesa sus opciones para usted de la manera en que lo hacen, por ejemplogetopts
, bash , elGetopt
módulo Perl o Pythonoptparse
/argparse
modules. Todo lo quegetopt
hace es canonizar las opciones que se pasan, es decir, convertirlas a una forma más estándar, para que sea más fácil para un script de shell procesarlas. Por ejemplo, una aplicación degetopt
podría convertir lo siguiente:dentro de esto:
Tienes que hacer el procesamiento real tú mismo. No tiene que usarlo
getopt
en absoluto si establece varias restricciones en la forma en que puede especificar opciones:-o
arriba), el valor debe ir como un argumento separado (después de un espacio).¿Por qué usar en
getopt
lugar degetopts
? La razón básica es que solo GNUgetopt
le brinda soporte para las opciones de línea de comandos de nombre largo. 1 (GNUgetopt
es el valor predeterminado en Linux. Mac OS X y FreeBSD vienen con unagetopt
versión básica y no muy útil , pero la versión GNU se puede instalar; ver más abajo).Por ejemplo, aquí hay un ejemplo del uso de GNU
getopt
, de un script mío llamadojavawrap
:Esto le permite especificar opciones como
--verbose -dm4096 --minh=20 --maxhe 40 --debugfi="/Users/John Johnson/debug.txt"
o similar. El efecto de la llamada agetopt
es canonizar las opciones para--verbose -d -m 4096 --minheap 20 --maxheap 40 --debugfile "/Users/John Johnson/debug.txt"
que pueda procesarlas más fácilmente. La cita alrededor"$1"
y"$2"
es importante ya que garantiza que los argumentos con espacios en ellos se manejen correctamente.Si elimina las primeras 9 líneas (todo a través de la
eval set
línea), ¡el código seguirá funcionando ! Sin embargo, su código será mucho más exigente en el tipo de opciones que acepta: en particular, tendrá que especificar todas las opciones en el formulario "canónico" descrito anteriormente. Singetopt
embargo, con el uso de , puede agrupar opciones de una sola letra, usar formas más cortas y no ambiguas de opciones largas, usar el estilo--file foo.txt
o--file=foo.txt
, usar el estilo-m 4096
o-m4096
, mezclar opciones y no opciones en cualquier orden, etc.getopt
también genera un mensaje de error si se encuentran opciones no reconocidas o ambiguas.NOTA : En realidad, hay dos versiones totalmente diferentes de
getopt
, basicgetopt
y GNUgetopt
, con diferentes características y diferentes convenciones de llamadas. 2 Basicgetopt
está bastante roto: no solo no maneja opciones largas, sino que ni siquiera puede manejar espacios incrustados dentro de argumentos o argumentos vacíos, mientrasgetopts
que lo hace bien. El código anterior no funcionará en básicogetopt
. GNUgetopt
se instala por defecto en Linux, pero en Mac OS X y FreeBSD necesita instalarse por separado. En Mac OS X, instale MacPorts ( http://www.macports.org ) y luegosudo port install getopt
instale GNUgetopt
(generalmente en/opt/local/bin
), y asegúrese de que/opt/local/bin
esté en su ruta de shell antes de/usr/bin
. En FreeBSD, instalemisc/getopt
.Una guía rápida para modificar el código de ejemplo para su propio programa: de las primeras líneas, todas son "repetitivas" que deben permanecer igual, excepto la línea que llama
getopt
. Debe cambiar el nombre del programa después-n
, especificar opciones cortas después-o
y opciones largas después--long
. Poner dos puntos después de las opciones que toman un valor.Finalmente, si ve un código que tiene solo en
set
lugar deeval set
, fue escrito para BSDgetopt
. Debe cambiarlo para usar eleval set
estilo, que funciona bien con ambas versiones degetopt
, mientras que el planoset
no funciona bien con GNUgetopt
.1 En realidad,
getopts
enksh93
soportes opciones nombrado largo, pero esta capa no se utiliza tan a menudo comobash
. Enzsh
, usezparseopts
para obtener esta funcionalidad.2 Técnicamente, "GNU
getopt
" es un nombre inapropiado; Esta versión fue escrita para Linux en lugar del proyecto GNU. Sin embargo, sigue todas las convenciones de GNU, y el término "GNUgetopt
" se usa comúnmente (por ejemplo, en FreeBSD).fuente
getopt
en Linux no es una utilidad GNU y lo tradicionalgetopt
no proviene inicialmente de BSD sino de AT&T Unix. ksh93'sgetopts
(también de AT&T) admite opciones largas de estilo GNU.POSIXLY_CORRECT
), mientras que "getopt mejorado por Linux" sugiere erróneamente que esta versión solo existe en Linuxgetopt
fácilmente podría ser portado a otros Unices, pero muchos otros programasutil-linux
son específicos de Linux). Todos los programas que no son GNU que utilizan GNU getopt (3) entienden$POSIX_CORRECT
. Por ejemplo, no diría queaplay
es GNU solo por esos motivos. Sospecho que cuando FreeBSD menciona GNU getopt, se refieren a GNU getopt (3) C API.getopt
utilidad, no a getopt (3).La función getopts incorporada de Bash se puede usar para analizar opciones largas poniendo un carácter de guión seguido de dos puntos en la especificación de operación:
Después de copiar al archivo ejecutable name =
getopts_test.sh
en el directorio de trabajo actual , uno puede producir resultados comoObviamente, getopts no realiza
OPTERR
comprobaciones ni analiza argumentos de opciones para las opciones largas. El fragmento de script anterior muestra cómo se puede hacer esto manualmente. El principio básico también funciona en el shell Debian Almquist ("guión"). Tenga en cuenta el caso especial:Tenga en cuenta que, como GreyCat de http://mywiki.wooledge.org/BashFAQ señala, este truco explota un comportamiento no estándar del shell que permite el argumento de opción (es decir, el nombre de archivo en "-f filename") ser concatenado a la opción (como en "-ffilename"). El estándar POSIX dice que debe haber un espacio entre ellos, que en el caso de "- longoption" terminaría el análisis de opciones y convertiría todas las longopciones en argumentos sin opciones.
fuente
!
inval="${!OPTIND}
?getopts
automáticamente solo se incrementaOPTIND
con 1, pero en nuestro caso necesitamos que se incremente en 2, por lo que lo incrementamos en 1 manualmente, luego dejamosgetopts
aumentarlo en 1 nuevamente para nosotros automáticamente.$
necesario.OPTIND=$(( $OPTIND + 1 ))
puede ser justoOPTIND=$(( OPTIND + 1 ))
. Aún más interesante, incluso puede asignar y aumentar variables dentro de una expresión aritmética, por lo que es posible abreviarla aún más: $(( ++OPTIND ))
, o incluso(( ++OPTIND ))
tener en cuenta que++OPTIND
siempre será positiva, por lo que no se disparará una ejecución de shell con la-e
opción. :-) gnu.org/software/bash/manual/html_node/Shell-Arithmetic.html--very-bad
da una advertencia?El
getopts
comando incorporado sigue siendo, AFAIK, limitado a las opciones de un solo carácter.Hay (o solía haber) un programa externo
getopt
que reorganizaría un conjunto de opciones para que fuera más fácil de analizar. También puede adaptar ese diseño para manejar opciones largas. Ejemplo de uso:Podría usar un esquema similar con un
getoptlong
comando.Tenga en cuenta que la debilidad fundamental con el
getopt
programa externo es la dificultad de manejar argumentos con espacios en ellos y de preservar esos espacios con precisión. Esta es la razón por la cual el incorporadogetopts
es superior, aunque limitado por el hecho de que solo maneja opciones de una letra.fuente
eval set
con comillas (ver mi respuesta a continuación) para que también funcione correctamente con GNU getopt (el valor predeterminado en Linux) y maneje los espacios correctamente.${1+"$@"}
es pintoresco y está en desacuerdo con lo que es necesario en los shells modernos y específicamente con cualquier shell que encuentre en Linux. Consulte Uso de $ 1: + "$ @"} en / bin / sh para obtener un discusión de esa notación.)eval set
hace lo correcto tanto con GNU como con BSDgetopt
, mientras que simplementeset
solo hace lo correcto con BSDgetopt
. Por lo tanto, puede utilizareval set
para alentar a las personas a adquirir el hábito de hacer esto. Por cierto, gracias, no me di cuenta de que${1+"$@"}
ya no era necesario. Tengo que escribir cosas que funcionen tanto en Mac OS X como en Linux: entre los dos fuerzan mucha portabilidad. Acabo de comprobar y"$@"
hace de hecho lo correcto en todossh
,bash
,ksh
, yzsh
en Mac OS X; seguramente bajo Linux también.Aquí hay un ejemplo que realmente usa getopt con opciones largas:
fuente
eval set
con comillas (vea mi respuesta a continuación) para que también funcione correctamente con GNU getopt (el valor predeterminado en Linux) y maneje los espacios correctamente.getopt
mientras se trata la preguntagetopts
.(--
,(-*
y(*
patrones válidos? ¿En qué son diferentes de--
,-*
y*
?(--)
es idéntico al--)
de unacase
estrofa. Es extraño ver la sangría desigual y el uso inconsistente de esos padres principales opcionales, pero el código actual de la respuesta me parece válido.Las opciones largas pueden ser analizadas por el estándar
getopts
incorporado como "argumentos" a la-
"opción"Este es un shell POSIX portátil y nativo: no se necesitan programas externos ni bashismos.
Esta guía implementa opciones largas como argumentos de la
-
opción, por lo que--alpha
se vegetopts
como-
con argumentoalpha
y--bravo=foo
se ve como-
con argumentobravo=foo
. El verdadero argumento puede ser cosechada con una simple sustitución:${OPTARG#*=}
.En este ejemplo,
-b
y-c
(y sus formas largas,--bravo
y--charlie
) tienen argumentos obligatorios. Los argumentos sobre las opciones largas aparecen después de signos iguales, por ejemplo--bravo=foo
(los delimitadores de espacio para opciones largas serían difíciles de implementar, ver más abajo).Debido a que este utiliza el
getopts
incorporado , este uso soportes como solucióncmd --bravo=foo -ac FILE
(que ha combinado opciones-a
y-c
e intercala largas opciones con opciones estándar), mientras que la mayoría de las otras respuestas aquí tampoco lucha o dejar de hacer eso.Cuando la opción es un guión (
-
), es una opción larga.getopts
habrá analizado la opción larga real en$OPTARG
, por ejemplo,--bravo=foo
establece originalmenteOPT='-'
yOPTARG='bravo=foo'
. Laif
estrofa se ajusta$OPT
al contenido de$OPTARG
antes del primer signo igual (bravo
en nuestro ejemplo) y luego elimina eso desde el principio de$OPTARG
(ceder=foo
en este paso, o una cadena vacía si no hay=
). Finalmente, despojamos el argumento principal=
. En este punto,$OPT
es una opción corta (un carácter) o una opción larga (más de 2 caracteres).La
case
continuación partidos ya sea a corto o largo opciones. Para las opciones cortas,getopts
se queja automáticamente sobre las opciones y los argumentos faltantes, por lo que tenemos que replicarlos manualmente usando laneeds_arg
función, que se cierra fatalmente cuando$OPTARG
está vacía. La??*
condición coincidirá con cualquier opción larga restante (?
coincide con un solo carácter y*
coincide con cero o más, por lo que??*
coincide con más de 2 caracteres), lo que nos permite emitir el error "Opción ilegal" antes de salir.(Una nota sobre nombres de variables en mayúsculas: en general, el consejo es reservar las variables en mayúsculas para el uso del sistema. Me mantengo
$OPT
como todo en mayúsculas para mantenerlo en línea$OPTARG
, pero esto rompe esa convención. Creo que es encaja porque esto es algo que el sistema debería haber hecho, y debería ser seguro porque no hay estándares (afaik) que usen dicha variable).Para quejarse de argumentos inesperados a opciones largas, imite lo que hicimos para argumentos obligatorios: use una función auxiliar. Simplemente voltee la prueba para quejarse de un argumento cuando no se espera uno:
Una versión anterior de esta respuesta tenía un intento de aceptar opciones largas con argumentos delimitados por espacios, pero no era confiable;
getopts
podría terminar prematuramente asumiendo que el argumento estaba más allá de su alcance y que el incremento manual$OPTIND
no funciona en todos los shells.Esto se lograría utilizando una de estas técnicas:
eval "bravo=\"\$$OPTIND\""
bravo="${!OPTIND}"
P
indicador :bravo="${(P)OPTIND}"
y luego concluí con algo como
[ $# -gt $OPTIND ] && OPTIND=$((OPTIND+1))
fuente
letter-c
no necesita argumentos, ¿no sería suficiente usarloletter-c)
? El*
parece redundante.getopts
se detiene en el primer argumento posicional ya que no está diseñado para tratar con ellos. Esto permite subcomandos con sus propios argumentos, por ejemplogit diff --color
, por lo que interpretaríacommand --foo=moo bar --baz waz
que tienen--foo
como argumentocommand
y--baz waz
como argumento (con opción) albar
subcomando. Esto se puede hacer con el código anterior. Rechazo--bravo -blah
porque--bravo
requiere un argumento y no está claro que esa-blah
no sea otra opción.eval
en el shell POSIX, aparece debajo del resto de la respuesta.Eche un vistazo a shFlags, que es una biblioteca de shell portátil (es decir: sh, bash, dash, ksh, zsh en Linux, Solaris, etc.).
Hace que agregar nuevas marcas sea tan simple como agregar una línea a su script, y proporciona una función de uso generada automáticamente.
Aquí hay un simple
Hello, world!
uso de shFlag :Para los sistemas operativos que tienen el getopt mejorado que admite opciones largas (por ejemplo, Linux), puede hacer lo siguiente:
Por lo demás, debe usar la opción corta:
Agregar una nueva bandera es tan simple como agregar una nueva
DEFINE_ call
.fuente
Usar
getopts
con opciones cortas / largas y argumentosFunciona con todas las combinaciones, por ejemplo:
Algunas declaraciones para este ejemplo
Cómo se vería la función de uso
getops
con banderas largas / cortas, así como argumentos largosSalida
Combinando lo anterior en un guión coherente
fuente
eval
enfoque de argumentos espaciados en opciones largas y me pareció poco confiable con ciertos shells (aunque espero que funcione con bash, en cuyo caso no tiene que usarloeval
). Vea mi respuesta sobre cómo aceptar argumentos de opciones largas=
y mis intentos notables de usar el espacio. Mi solución no hace llamadas externas, mientras que esta se usacut
varias veces.De otra manera...
fuente
$args
reasignación? Esto incluso podría hacerse sin bashisms, pero este código perderá espacios en opciones y argumentos (no creo que el$delim
truco funcione). En su lugar, puede ejecutarset
dentro delfor
bucle si tiene cuidado de vaciarlo solo en la primera iteración. Aquí hay una versión más segura sin bashismos.Lo resolví de esta manera:
¿Estoy siendo tonto o algo así?
getopt
ygetopts
son muy confusosfuente
-ltr
o-lt -r
también-l -t -r
). Y también proporciona cierto manejo de errores, y una manera fácil de cambiar los parámetros tratados una vez que finaliza el tratamiento de opciones.En caso de que no desee la
getopt
dependencia, puede hacer esto:Por supuesto, entonces no puedes usar opciones de estilo largas con un guión. Y si desea agregar versiones abreviadas (por ejemplo, --verbos en lugar de --verbose), debe agregarlas manualmente.
Pero si está buscando obtener
getopts
funcionalidad junto con opciones largas, esta es una manera simple de hacerlo.También puse este fragmento en una esencia .
fuente
--)
parece haber unashift ;
falta. Por el momento--
, permanecerá como primer argumento sin opción.--
opción necesita unashift
allí. Yo digo que esto es mejor porque las alternativas son o bien plataforma de versiones dependientes degetopt
ogetopts_long
o tiene que forzar cortos opciones para ser utilizado sólo en el inicio de la orden (es decir, - se utilizagetopts
luego procesar las opciones largas después), mientras que esto da cualquier orden y control completo.El incorporado
getopts
no puede hacer esto. Hay un programa getopt (1) externo que puede hacer esto, pero solo lo obtienes en Linux desde el paquete util-linux . Viene con un script de ejemplo getopt-parse.bash .También hay una función
getopts_long
escrita como shell.fuente
getopt
incluyó en FreeBSD versión 1.0 en 1993, y ha sido parte de FreeBSD desde entonces. Como tal, fue adoptado de FreeBSD 4.x para su inclusión en el proyecto Darwin de Apple. A partir de OS X 10.6.8, la página de manual incluida por Apple sigue siendo un duplicado exacto de la página de manual de FreeBSD. Entonces sí, está incluido en OS X y en muchos otros sistemas operativos además de Linux. -1 en esta respuesta para la desinformación..
fuente
"${1:0:1}"
para el argumento # 1, subcadena en el índice 0, longitud 1. Esto no permite mezclar opciones cortas y largas.En
ksh93
,getopts
admite nombres largos ...O eso dicen los tutoriales que he encontrado. Pruébalo y verás.
fuente
Solo escribo scripts de shell de vez en cuando y caigo en la práctica, por lo que cualquier comentario es apreciado.
Usando la estrategia propuesta por @Arvid Requate, notamos algunos errores de los usuarios. Un usuario que olvida incluir un valor accidentalmente tendrá el nombre de la siguiente opción tratado como un valor:
hará que el valor de "loglevel" se vea como "--toc = TRUE". Esto se puede evitar.
Adapte algunas ideas sobre la comprobación de errores de usuario para CLI de http://mwiki.wooledge.org/BashFAQ/035 discusión del análisis manual. Inserté la comprobación de errores en el manejo de los argumentos "-" y "-".
Luego comencé a jugar con la sintaxis, por lo que cualquier error aquí es estrictamente mi culpa, no los autores originales.
Mi enfoque ayuda a los usuarios que prefieren ingresar mucho tiempo con o sin el signo igual. Es decir, debería tener la misma respuesta a "--loglevel 9" que "--loglevel = 9". En el método - / space, no es posible saber con certeza si el usuario olvida un argumento, por lo que es necesario adivinar.
En caso de que esté comenzando con esto, hay una diferencia interesante entre los formatos "--opt = value" y "--opt value". Con el signo igual, el argumento de la línea de comando se ve como "opt = value" y el trabajo a manejar que es el análisis de cadenas, para separar en el "=". En contraste, con "--opt value", el nombre del argumento es "opt" y tenemos el desafío de obtener el siguiente valor proporcionado en la línea de comando. Ahí es donde @Arvid Requate utilizó $ {! OPTIND}, la referencia indirecta. Todavía no entiendo eso, bueno, en absoluto, y los comentarios en BashFAQ parecen advertir contra ese estilo ( http://mywiki.wooledge.org/BashFAQ/006 ). Por cierto, no creo que los comentarios del póster anterior sobre la importancia de OPTIND = $ (($ OPTIND + 1)) sean correctos. Quiero decir,
En la versión más reciente de este script, flag -v significa impresión VERBOSA.
Guárdelo en un archivo llamado "cli-5.sh", haga ejecutable y cualquiera de estos funcionará o fallará de la manera deseada
Aquí hay un ejemplo de salida de la comprobación de errores en la intpu del usuario
Debería considerar activar -v, porque imprime los elementos internos de OPTIND y OPTARG
fuente
OPTIND=$(( $OPTIND + 1 ))
: es necesario siempre que 'engulle' el parámetro OPTIND (por ejemplo: cuando uno usó--toc value
: el valor está en el número de parámetro $ OPTIND. Una vez que lo recupere para el valor de toc, debe decirle a getopts que el siguiente parámetro para analizar no es el valor, peroOPTIND=$(( $OPTIND + 1 ))
falta el siguiente (de ahí el:. y su secuencia de comandos (así como la secuencia de comandos a la que se refiere), después de que se hace:shift $(( $OPTIND -1 ))
(como los getopts salieron después de analizar los parámetros 1 a OPTIND-1, debe cambiarlos así que$@
es ahora cualquier parámetro "no opciones" restanteInventando otra versión de la rueda ...
Esta función es (con suerte) un reemplazo de shell de bourne simple compatible con POSIX para GNU getopt. Admite opciones cortas / largas que pueden aceptar argumentos obligatorios / opcionales / sin argumentos, y la forma en que se especifican las opciones es casi idéntica a la getopt de GNU, por lo que la conversión es trivial.
Por supuesto, esto sigue siendo una porción considerable de código para colocar en un script, pero es aproximadamente la mitad de las líneas de la conocida función de shell getopt_long, y podría ser preferible en los casos en que solo desee reemplazar los usos existentes de GNU getopt.
Este es un código bastante nuevo, por lo que YMMV (y definitivamente avíseme si esto no es realmente compatible con POSIX por alguna razón; la portabilidad fue la intención desde el principio, pero no tengo un entorno de prueba POSIX útil).
El código y el ejemplo de uso son los siguientes:
Ejemplo de uso:
fuente
La respuesta aceptada hace un muy buen trabajo al señalar todas las deficiencias de bash incorporado
getopts
. La respuesta termina con:Y aunque en principio estoy de acuerdo con esa afirmación, creo que la cantidad de veces que todos implementamos esta característica en varios scripts justifica poner un poco de esfuerzo en crear una solución "estandarizada" y bien probada.
Como tal, he "actualizado" bash integrado
getopts
mediante la implementacióngetopts_long
en bash puro, sin dependencias externas. El uso de la función es 100% compatible con el incorporadogetopts
.Al incluir
getopts_long
(que está alojado en GitHub ) en un script, la respuesta a la pregunta original se puede implementar de la siguiente manera:fuente
Todavía no tengo suficiente representante para comentar o votar su solución, pero la respuesta de sme funcionó extremadamente bien para mí. El único problema con el que me topé fue que los argumentos terminan envueltos en comillas simples (así que tengo una tira de ellos).
También agregué algunos usos de ejemplo y texto de AYUDA. Incluiré mi versión ligeramente extendida aquí:
fuente
Aquí puede encontrar algunos enfoques diferentes para el análisis de opciones complejas en bash: http://mywiki.wooledge.org/ComplexOptionParsing
Creé el siguiente, y creo que es bueno, porque es un código mínimo y funcionan tanto las opciones largas como las cortas. Una opción larga también puede tener múltiples argumentos con este enfoque.
fuente
He estado trabajando en ese tema durante bastante tiempo ... e hice mi propia biblioteca que necesitarás encontrar en tu script principal. Vea libopt4shell y cd2mpc para un ejemplo. Espero eso ayude !
fuente
Una solución mejorada:
fuente
Quizás sea más simple usar ksh, solo para la parte de getopts, si necesita opciones de línea de comando largas, ya que puede ser más fácil hacerlo allí.
fuente
Quería algo sin dependencias externas, con estricto soporte de bash (-u), y lo necesitaba para funcionar incluso en las versiones de bash más antiguas. Esto maneja varios tipos de parámetros:
Simplemente inserte lo siguiente en la parte superior de su script:
Y úsalo así:
fuente
Para mantener la compatibilidad multiplataforma y evitar la dependencia de ejecutables externos, porté un código de otro idioma.
Me resulta muy fácil de usar, aquí hay un ejemplo:
El BASH requerido es un poco más largo de lo que podría ser, pero quería evitar depender de los arrays asociativos de BASH 4. También puede descargar esto directamente desde http://nt4.com/bash/argparser.inc.sh
fuente
Si todas sus opciones largas tienen primeros caracteres únicos y coincidentes como las opciones cortas, por ejemplo,
Es lo mismo que
Puedes usar esto antes de getopts para reescribir $ args:
Gracias por mtvee por la inspiración ;-)
fuente
si simplemente así es como quieres llamar al script
entonces puede seguir esta forma más sencilla de lograrlo con la ayuda de getopt y --longoptions
intente esto, espero que esto sea útil
fuente
getopts "podría usarse" para analizar opciones largas siempre y cuando no esperes que tengan argumentos ...
Aquí se explica cómo:
Si intenta utilizar OPTIND para obtener un parámetro para la opción larga, getopts lo tratará como el primer parámetro posicional no opcional y dejará de analizar cualquier otro parámetro. En tal caso, será mejor que lo manejes manualmente con una simple declaración de caso.
Esto "siempre" funcionará:
Aunque no es tan flexible como getopts y usted tiene que hacer la mayor parte del código de verificación de errores usted mismo dentro de las instancias del caso ...
Pero es una opción.
fuente
La función integrada
getopts
solo analiza opciones cortas (excepto en ksh93), pero aún puede agregar algunas líneas de secuencias de comandos para que getopts maneje opciones largas.Aquí hay una parte del código que se encuentra en http://www.uxora.com/unix/shell-script/22-handle-long-options-with-getopts
Aquí hay una prueba:
De lo contrario, en el reciente Korn Shell ksh93,
getopts
naturalmente puede analizar opciones largas e incluso mostrar una página de manual por igual. (Ver http://www.uxora.com/unix/shell-script/20-getopts-with-man-page-and-long-options )fuente
Th incorporado en OS X (BSD) getopt no es compatible con las opciones largas, pero la versión de GNU hace:
brew install gnu-getopt
. Entonces, algo similar a:cp /usr/local/Cellar/gnu-getopt/1.1.6/bin/getopt /usr/local/bin/gnu-getopt
.fuente
EasyOptions maneja opciones cortas y largas:
fuente