EDIT: Por favor, por favor , por favor, lea los dos requisitos que figuran en la parte inferior de este post antes de responder. La gente sigue publicando sus nuevas gemas y bibliotecas y todo eso, que claramente no cumplen con los requisitos.
A veces quiero piratear algunas opciones de la línea de comandos de forma muy económica en un script simple. Una forma divertida de hacerlo, sin tener que lidiar con getopts o parsing ni nada de eso, es:
...
$quiet = ARGV.delete('-d')
$interactive = ARGV.delete('-i')
...
# Deal with ARGV as usual here, maybe using ARGF or whatever.
No es del todo la sintaxis de opciones normal de Unix, porque acepta opciones que no son parámetros de línea de comandos de opciones, como en " myprog -i foo bar -q
", pero puedo vivir con eso. (Algunas personas, como los desarrolladores de Subversion, prefieren esto. A veces yo también.)
Una opción que está presente o ausente no se puede implementar de manera mucho más simple que la anterior. (Una asignación, una llamada a función, un efecto secundario). ¿Existe una forma igualmente sencilla de tratar las opciones que toman un parámetro, como " -f
nombre de archivo "?
EDITAR:
Un punto que no mencioné antes, porque no me había quedado claro hasta que el autor de Trollop mencionó que la biblioteca cabía "en un archivo [de 800 líneas]", es que no solo estoy buscando sintaxis, pero para una técnica que tiene las siguientes características:
La totalidad del código se puede incluir en el archivo de secuencia de comandos (sin abrumar la secuencia de comandos en sí, que puede ser solo un par de docenas de líneas), de modo que uno puede colocar un solo archivo en un
bin
directorio en cualquier sistema con un Ruby 1.8 estándar . [5-7] instalación y uso. Si no puede escribir una secuencia de comandos de Ruby que no tenga declaraciones de requerimiento y donde el código para analizar un par de opciones tenga menos de una docena de líneas, no cumple con este requisito.El código es lo suficientemente pequeño y simple como para que uno pueda recordar lo suficiente como para escribir directamente el código que funcionará, en lugar de cortar y pegar desde otro lugar. Piense en la situación en la que se encuentra en la consola de un servidor con cortafuegos sin acceso a Internet y desea preparar un script rápido para que lo use un cliente. No sé ustedes, pero (además de fallar el requisito anterior) memorizar incluso las 45 líneas de micro-optparse simplificado no es algo que me interese hacer.
getoptlong
yoptparse
están en la biblioteca de rubí estándar, por lo que no es necesario copiarlos al desplegar su guión - si rubí funciona en esa máquina, a continuación,require 'optparse'
orequire 'getoptlong'
también funcionará.Respuestas:
Como autor de Trollop , no puedo CREER las cosas que la gente piensa que es razonable en un analizador de opciones. Seriamente. Aturde la mente.
¿Por qué debería tener que hacer un módulo que amplíe algún otro módulo para analizar las opciones? ¿Por qué debería tener que subclasificar algo? ¿Por qué debería suscribirme a algún "marco" sólo para analizar la línea de comandos?
Aquí está la versión Trollop de lo anterior:
Y eso es.
opts
ahora es un hash con las teclas:quiet
,:interactive
y:filename
. Puedes hacer lo que quieras con eso. Y obtienes una hermosa página de ayuda, formateada para adaptarse al ancho de tu pantalla, nombres cortos automáticos de argumentos, verificación de tipos ... todo lo que necesitas.Es un archivo, por lo que puede colocarlo en su directorio lib / si no desea una dependencia formal. Tiene un DSL mínimo que es fácil de captar.
LOC por opción personas. Importa.
fuente
Comparto su disgusto por
require 'getopts'
, principalmente debido a la genialidad que esOptionParser
:fuente
Esta es la técnica estándar que suelo usar:
fuente
lib
carpeta o código y usarlo sin siquiera tocar rubygems.when /^-/ then usage("Unknown option: #{ARGV[0].inspect}")
awhen /^-/ then usage("Unknown option: #{ARGV.shift.inspect}")
o entraría en un ciclo de uso infinitoDado que nadie pareció mencionarlo, y el título se refiere a un análisis de línea de comandos barato , ¿por qué no dejar que el intérprete Ruby haga el trabajo por usted? Si pasa el
-s
interruptor (en su shebang, por ejemplo), obtiene interruptores muy simples de forma gratuita, asignados a variables globales de una sola letra. Aquí está su ejemplo usando ese interruptor:Y aquí está la salida cuando guardo eso como
./test
y lo modifico+x
:Consulte
ruby -h
para obtener más detalles.Eso debe ser tan barato como se pone. Generará un NameError si prueba un cambio como
-:
, por lo que hay algo de validación allí. Por supuesto, no puede tener ningún cambio después de un argumento sin cambio, pero si necesita algo sofisticado, realmente debería usar como mínimo OptionParser. De hecho, lo único que me molesta de esta técnica es que recibirás una advertencia (si las has habilitado) cuando accedas a una variable global no configurada, pero sigue siendo falsa, por lo que funciona bien para herramientas desechables y rápidas. guiones.Una advertencia señalada por FelipeC en los comentarios en " Cómo hacer un análisis de opciones de línea de comandos realmente barato en Ruby ", es que su shell podría no ser compatible con el shebang de 3 tokens; es posible que deba reemplazar
/usr/bin/env ruby -w
con la ruta real a su ruby (como/usr/local/bin/ruby -w
), o ejecutarlo desde un script contenedor, o algo así.fuente
Construí micro-optparse para esta obvia necesidad de un analizador de opciones corto pero fácil de usar. Tiene una sintaxis similar a Trollop y tiene 70 líneas cortas. Si no necesita validaciones y puede prescindir de las líneas vacías, puede reducirlo a 45 líneas. Creo que eso es exactamente lo que estabas buscando.
Ejemplo corto:
Llamar al script con
-h
o--help
imprimiráComprueba si la entrada es del mismo tipo que el valor predeterminado, genera accesos cortos y largos, imprime mensajes de error descriptivos si se dan argumentos no válidos y más.
Yo comparé varias opciones-analizador mediante el uso de cada opción-analizador para el problema que tenía. Puede utilizar estos ejemplos y mi resumen para tomar una decisión informativa. No dude en agregar más implementaciones a la lista. :)
fuente
optparse
cuál es (más o menos) 1937 líneas?optparse
es una biblioteca predeterminada, es decir, se envía con cada instalación de Ruby.Trollop
es una biblioteca de terceros, por lo que debe importar el código completo cada vez que desee incluirlo en un proyecto. µ-optparse siempre solo requiere las ~ 70 líneas, yaoptparse
que ya están ahí.Entiendo totalmente por qué desea evitar optparse: puede ser demasiado. Pero hay algunas soluciones mucho más "ligeras" (en comparación con OptParse) que vienen como bibliotecas pero son lo suficientemente simples como para hacer que valga la pena instalar una sola gema.
Por ejemplo, consulte este ejemplo de OptiFlag . Solo unas pocas líneas para el procesamiento. Un ejemplo ligeramente truncado adaptado a su caso:
También hay toneladas de ejemplos personalizados . Recuerdo haber usado otro que era aún más fácil, pero se me ha escapado por ahora, pero volveré y agregaré un comentario aquí si lo encuentro.
fuente
Esto es lo que uso para argumentos realmente baratos:
así que si lo ejecutas
programname foo bar
llama a foo y luego a bar. Es útil para guiones desechables.fuente
Puedes probar algo como:
fuente
¿Has considerado a Thor? por wycats? Creo que es mucho más limpio que optparse. Si ya tiene un script escrito, podría ser un poco más trabajo formatearlo o refactorizarlo para Thor, pero hace que las opciones de manejo sean muy simples.
Aquí está el fragmento de ejemplo del archivo README:
Thor mapea automáticamente los comandos como tales:
Eso se convierte en:
fuente
--help
salida? ¿Qué pasa si "head myprogram.rb" fuera la salida de ayuda?Aquí está mi analizador de opciones rápido y sucio favorito:
Las opciones son expresiones regulares, por lo que "-h" también coincidiría con "--help".
Legible, fácil de recordar, sin biblioteca externa y código mínimo.
fuente
/-h(\b|elp)
Trollop es bastante barato.
fuente
Si desea un analizador de línea de comando simple para comandos clave / valor sin el uso de gemas:
Pero esto solo funciona si siempre tiene pares clave / valor.
Si no necesita ninguna verificación , puede usar:
fuente
Aquí está el fragmento de código que utilizo en la parte superior de la mayoría de mis scripts:
También odio requerir archivos adicionales en mis scripts rápidos y sucios. Mi solución es casi lo que estás pidiendo. Pego un fragmento de código de 10 líneas en la parte superior de cualquiera de mis scripts que analiza la línea de comando y pega argumentos posicionales y cambia a un objeto Hash (generalmente asignado a un objeto que he llamado arghash en los ejemplos a continuación).
Aquí hay una línea de comando de ejemplo que quizás desee analizar ...
Que se convertiría en un hash como este.
Además de eso, se agregan dos métodos de conveniencia al Hash:
argc()
devolverá el recuento de argumentos que no son de cambio.switches()
devolverá una matriz que contiene las claves para los interruptores que están presentesEsto es para permitir algunas cosas rápidas y sucias como ...
arghash.argc == 2
)arghash[1]
siempre obtiene el segundo argumento que no es el interruptor).arghash['--max=']
cual se obtiene un valor de '15' dada la línea de comando de ejemplo.arghash['-s']
que se evalúa como verdadero si está presente y nulo si está ausente.Pruebe la presencia de un interruptor o alternativas de interruptores usando operaciones establecidas como
puts USAGETEXT if !(%w(-h --help) & arghash.switches()).empty?
Identificar el uso de interruptores no válidos mediante operaciones de configuración como
puts "Invalid switch found!" if !(arghash.switches - %w(-valid1 -valid2)).empty?
Especifique los valores predeterminados para los argumentos que faltan usando un
Hash.merge()
ejemplo simple como el siguiente, que completa un valor para -max = si no se estableció uno y agrega un cuarto argumento posicional si no se pasó uno.with_defaults = {'-max=' => 20, 3 => 'default.txt'}.merge(arghash)
fuente
=
) puede marcar la diferencia en el código que necesita.Esto es muy similar a la respuesta aceptada, pero usando
ARGV.delete_if
cuál es lo que uso en mi analizador simple . La única diferencia real es que las opciones con argumentos deben estar juntas (p-l=file
. Ej .).fuente
Aparentemente @WilliamMorgan y yo pensamos igual. Acabo de publicar anoche en Github lo que ahora veo es una biblioteca similar a Trollop (¿nombrada cómo?) Después de haber hecho una búsqueda de OptionParser en Github, consulte Switches
Hay algunas diferencias, pero la filosofía es la misma. Una diferencia obvia es que Switches depende de OptionParser.
fuente
Estoy desarrollando mi propia gema de analizador de opciones llamada Acclaim .
Lo escribí porque quería crear interfaces de línea de comandos de estilo git y poder separar limpiamente la funcionalidad de cada comando en clases separadas, pero también se puede usar sin el marco de comandos completo:
Aún no hay una versión estable, pero ya he implementado algunas características como:
Hay mucho énfasis en los comandos, por lo que puede ser un poco pesado para el análisis simple de la línea de comandos, pero funciona bien y lo he estado usando en todos mis proyectos. Si está interesado en el aspecto de la interfaz de comandos, consulte la página de GitHub del proyecto para obtener más información y ejemplos.
fuente
Suponga que un comando tiene como máximo una acción y un número arbitrario de opciones como esta:
El análisis sin validación puede ser así:
fuente
https://github.com/soveran/clap
46LOC (en 1.0.0), sin dependencia del analizador de opciones externo. Hace el trabajo. Probablemente no sea tan completo como otros, pero es 46LOC.
Si verifica el código, puede duplicar con bastante facilidad la técnica subyacente: asigne lambdas y use la aridad para asegurarse de que el número adecuado de argumentos siga la marca si realmente no desea una biblioteca externa.
Sencillo. Barato.
EDITAR : el concepto subyacente se redujo, ya que supongo que podría copiarlo / pegarlo en un script para hacer un analizador de línea de comando razonable. Definitivamente no es algo que me gustaría memorizar, pero usar el lambda arity como un analizador barato es una idea novedosa:
fuente
Voy a compartir mi propio analizador de opciones simple en el que he estado trabajando durante algún tiempo. Son solo 74 líneas de código, y hace lo básico de lo que hace el analizador de opciones interno de Git. Tomé OptionParser como inspiración, y también la de Git.
https://gist.github.com/felipec/6772110
Se parece a esto:
fuente
EasyOptions no requiere ningún código de análisis de opciones. Simplemente escriba el texto de ayuda, requiera, listo.
fuente