2009-07-29 11 views
138

Escribo una pequeña aplicación de línea de comandos en Java. Esta aplicación debería funcionar con una combinación de parámetros y comandos, similar a svn.Biblioteca de Java para analizar los parámetros de línea de comandos?


Ejemplos

app url command1 
app url command2 --parameter2 -x 
app url command1 --param-with-argument argument 
app --parameter url command1 
app --no-url command2 
app --help 


deseada

  • Existe una biblioteca de fácil uso para Ja VA
  • Soporta análisis de tales líneas de comandos
  • (Bonus) crea automáticamente una ayuda adecuada
+1

Pregunta anterior muy relacionada: http://stackoverflow.com/questions/435740/are-there-good-java-libraries-that-facilitate-building-command-line-applications – Jonik

+1

posible duplicado de [¿Hay un buen analizador de argumentos de línea de comandos para Java?] (http://stackoverflow.com/questions/367706/is-there-a-good-command-line-argument-parser-for-java) –

+1

Esta es una buena pregunta que merece estar en http://softwarerecs.stackexchange.com/. –

Respuesta

82

Soy un fan de Commons CLI.

Puede configurarlo para que comprenda los comandos, los indicadores (con nombres cortos y largos), si se requieren ciertos comandos/conmutadores o si tienen valores predeterminados. Incluso tiene la funcionalidad para imprimir un útil mensaje de tipo --help.

La página Usage Scenarios tiene algunos buenos ejemplos de cómo se puede utilizar.

+0

Hy. Ha pasado mucho tiempo, pero no puedo conseguir que apache cli capte mis comandos, solo banderas. Y no puedo encontrar un ejemplo para eso. =/ –

54

Trate args4j:http://args4j.kohsuke.org

prefiero a args4j Commons CLI. (Y he usado ambos.)

Con args4j, no necesita llamar a ninguna función. ¡Todo está hecho para ti! (Los parámetros se establecen en los campos del objeto a través de la reflexión.)

+10

También usamos args4j. Un inconveniente es que no puede especificar opciones multivalor en el estilo de '-file input1.txt input2.txt'. Debe especificar el cambio de opción antes de cada valor nuevamente ('-file input1.txt -file input2.txt') lo cual puede ser una desventaja si desea usar la expansión bash (entonces' -file input * .txt' is ** no ** posible) – MRalwasser

+2

El proyecto se movió a http://args4j.kohsuke.org/ –

+0

Las opciones de valores múltiples ya no son compatibles a partir de args4j 2.0.23 ... – ochedru

28

JewelCLI es un Java library for command-line parsing that yields clean code. Utiliza las interfaces proxy configuradas con anotaciones para construir dinámicamente una API segura para sus parámetros de línea de comandos.

Un ejemplo de interfaz de parámetros Person.java:

import uk.co.flamingpenguin.jewel.cli.Option; 

public interface Person { 
    @Option String getName(); 
    @Option int getTimes(); 
} 

Un ejemplo de uso de la interfaz de parámetros Hello.java:

import static uk.co.flamingpenguin.jewel.cli.CliFactory.parseArguments; 
import uk.co.flamingpenguin.jewel.cli.ArgumentValidationException; 

public class Hello { 
    public static void main(String [] args) { 
     try { 
      Person person = parseArguments(Person.class, args); 
      for (int i = 0; i < person.getTimes(); i++) 
       System.out.println("Hello " + person.getName()); 
     } catch(ArgumentValidationException e) { 
      System.err.println(e.getMessage()); 
     } 
    } 
} 

Guardar copias de los archivos anteriores a un solo directorio y descargar el JewelCLI 0.7.6 JAR a ese directorio también.

Compila y ejecuta el ejemplo en Bash en Linux/Mac OS X/etc.:

javac -cp jewelcli-0.7.6.jar:. Person.java Hello.java 
java -cp jewelcli-0.7.6.jar:. Hello --name="John Doe" --times=3 

compilar y ejecutar el ejemplo en el símbolo del sistema de Windows:

javac -cp jewelcli-0.7.6.jar;. Person.java Hello.java 
java -cp jewelcli-0.7.6.jar;. Hello --name="John Doe" --times=3 

Ejecutar el ejemplo debe dar el siguiente resultado:

Hello John Doe 
Hello John Doe 
Hello John Doe 
+0

Como puede ver, JewelCLI hace que el análisis de línea de comandos sea simple y escriba seguro. Tampoco tiene equipaje de dependencia para arrastrar, lo que es una rareza en estos días. –

+0

Gracias por la corrección de URL @deterb :) –

+0

Gracias por las correcciones de enlace @flamingpenguin :) –

3

JSAP se ve muy bien para mí.

http://sourceforge.net/projects/jsap/

+0

Información: Último archivo publicado de JSAP había sido en 2006 – MRalwasser

+0

Puede ser viejo, pero todavía funciona como un encanto para mí. Sin embargo, dependencias complicadas como "Si se proporciona el parámetro A, el parámetro B debe ser más pequeño que A" no se puede expresar automáticamente. – kap

15

Es también digno de mirar --jopt-simple.

Intenta respetar las sintaxis de la opción de línea de comandos de POSIX getopt() y GNU getopt_long(). ' Parece tener algo de tracción en la comunidad, notablemente es la línea de comando que analiza la lib de elección para el OpenJDK (¡y Minecraft!).

19

Para completarlo vamos a añadir JCommander https://github.com/cbeust/jcommander

public class JCommanderTest { 
    @Parameter 
    public List<String> parameters = Lists.newArrayList(); 

    @Parameter(names = { "-log", "-verbose" }, description = "Level of verbosity") 
    public Integer verbose = 1; 

    @Parameter(names = "-groups", description = "Comma-separated list of group names to be run") 
    public String groups; 

    @Parameter(names = "-debug", description = "Debug mode") 
    public boolean debug = false; 
} 

y un ejemplo de uso

CommanderTest jct = new JCommanderTest(); 
String[] argv = { "-log", "2", "-groups", "unit", "a", "b", "c" }; 
new JCommander(jct, argv); 

Assert.assertEquals(jct.verbose.intValue(), 2); 
+1

de http://jcommander.org/: "JCommander: porque la vida es demasiado corta para analizar parámetros de línea de comandos". –

+0

¡Acabo de probar la biblioteca de Commons CLI, encontré que es extremadamente frustrante de usar, me cambié a JCommander y no me arrepiento! Algo tan simple como aceptar opciones desconocidas fue ridículamente complicado de lograr con Commons CLI. Es un trazador de líneas por otro lado con JCommander. –

3

estoy usando puente aéreo para un proyecto que estoy trabajando, parece que funciona bastante bien:

https://github.com/airlift/airline

Simple Maven dependen dencia de que es necesario agregar:

<dependency> 
    <groupId>io.airlift</groupId> 
    <artifactId>airline</artifactId> 
    <version>0.6</version> 
</dependency> 

Y después de eso es sobre la base de anotación y tiene una manera bastante ordenada de mostrar el texto de ayuda también.

puede ver un ejemplo aquí si es útil:

https://github.com/mneedham/neo4j-web-importer/blob/master/src/main/java/org/neo4j/dataimport/Neo4jImporter.java

+1

Desafortunadamente, esto arrastra una dependencia de 1.8 MB (Guava). El tamaño de la utilidad de línea de comandos que estoy escribiendo aumentó en un factor de 10, solo para admitir opciones de línea de comandos ... – cambecc

52

He aquí una lista relativamente al día (Desde la Ago 2017) de bibliotecas que respondan a su pregunta.

Si usted está buscando una recomendación, recomiendo JOpt simple o JewelCli.

+2

JCommander es uno de los más actualizados en esta lista. –

+3

En cuanto al 12 de mayo de 2015, JOpt Simple todavía se usa en OpenJDK. Ese parece ser el testimonio más útil que se me ocurre. – Ivar

+2

Sí, Ivar, estoy de acuerdo contigo en que JOpt Simple no solo es fácil de usar, sino completo. JCommander sería adecuado para aquellos con un fetiche para anotaciones vinculantes. –

4

Commandline está basado en anotaciones, permite reglas complejas para combinar argumentos (secuencias, anidamiento, argumentos, tipos, ...) y está razonablemente bien documentado.

Para usarlo, añadir

<dependency> 
    <groupId>com.github.jankroken</groupId> 
    <artifactId>commandline</artifactId> 
    <version>1.7.0</version> 
</dependency> 

a su pom, y declarar las opciones disponibles de la siguiente manera:

public class CommandOptions { 
    private List<String> commands = null; 
    private boolean parameter = false; 
    private boolean url = true; 
    private boolean help = false; 

    @LooseArguments 
    public void setCommands(List<String> commands) { 
    this.commands = commands; 
    } 

    @LongSwitch("parameter") 
    @Toggle(true) 
    public void setParameter(boolean parameter) { 
    this.parameter=parameter; 
    } 

    @LongSwitch("noURL") 
    @Toggle(false) 
    public void setUrl(boolean url) { 
    this.url = url; 
    } 

    @longSwitch("help") 
    @Toggle(true) 
    public void setHelp(boolean help) { 
    this.help = help; 
    } 

    // getters 
} 

y luego para realmente analizar la línea de comandos, haga

public final static void main(String[] args) { 
    try { 
    CommandOptions options = CommandLineParser.parse(CommandOptions.class, args, OptionStyle.SIMPLE); 

    // and then you can pass options to your application logic... 

    } catch 
    ... 
    } 
} 

tenga en cuenta que aún no contiene un texto de ayuda generado automáticamente. Esto fue prototipo, pero abortado. Es fácil generar un texto de ayuda básico para casos simples, pero para configuraciones más complejas (por ejemplo, las opciones disponibles para una aplicación como "buscar" o "gcc"), el resultado no será bonito, y es probable que prefiera controla el diseño tú mismo.

Cuestiones relacionadas