¿Cuál es una buena forma de analizar argumentos de línea de comandos en Java?
How to parse java command line arguments?
. Pero nadie realmente quiere escribir código para hacer esto, sino usar una herramienta. Pero la búsqueda de herramientas y
¿Cuál es una buena forma de analizar argumentos de línea de comandos en Java?
How to parse java command line arguments?
. Pero nadie realmente quiere escribir código para hacer esto, sino usar una herramienta. Pero la búsqueda de herramientas y
Respuestas:
Mira esto:
O rueda el tuyo:
Por ejemplo, así es como se utilizan commons-cli
para analizar 2 argumentos de cadena:
import org.apache.commons.cli.*;
public class Main {
public static void main(String[] args) throws Exception {
Options options = new Options();
Option input = new Option("i", "input", true, "input file path");
input.setRequired(true);
options.addOption(input);
Option output = new Option("o", "output", true, "output file");
output.setRequired(true);
options.addOption(output);
CommandLineParser parser = new DefaultParser();
HelpFormatter formatter = new HelpFormatter();
CommandLine cmd;
try {
cmd = parser.parse(options, args);
} catch (ParseException e) {
System.out.println(e.getMessage());
formatter.printHelp("utility-name", options);
System.exit(1);
}
String inputFilePath = cmd.getOptionValue("input");
String outputFilePath = cmd.getOptionValue("output");
System.out.println(inputFilePath);
System.out.println(outputFilePath);
}
}
uso desde la línea de comando:
$> java -jar target/my-utility.jar -i asd
Missing required option: o
usage: utility-name
-i,--input <arg> input file path
-o,--output <arg> output file
Echa un vistazo al JCommander más reciente .
Yo lo creé. Estoy feliz de recibir preguntas o solicitudes de funciones.
He estado tratando de mantener una lista de analizadores Java CLI .
Es 2020, es hora de hacerlo mejor que Commons CLI ... :-)
¿Debería crear su propio analizador de línea de comandos Java o utilizar una biblioteca?
Es probable que muchas pequeñas aplicaciones similares a servicios utilicen su propio análisis de línea de comandos para evitar la dependencia externa adicional. picocli puede ser una alternativa interesante.
Picocli es una biblioteca y un marco modernos para crear aplicaciones de línea de comandos potentes, fáciles de usar y habilitadas para GraalVM con facilidad. Vive en 1 archivo fuente, por lo que las aplicaciones pueden incluirlo como fuente para evitar agregar una dependencia.
Admite colores, autocompletado, subcomandos y más. Escrito en Java, utilizable desde Groovy, Kotlin, Scala, etc.
caracteristicas:
<command> -xvfInputFile
así como <command> -x -v -f InputFile
)"1..*"
,"3..5"
El mensaje de ayuda de uso es fácil de personalizar con anotaciones (sin programación). Por ejemplo:
( fuente )
No pude resistirme a agregar una captura de pantalla más para mostrar qué mensajes de ayuda de uso son posibles. La ayuda de uso es la cara de su aplicación, ¡así que sea creativo y diviértase!
Descargo de responsabilidad: creé picocli. Comentarios o preguntas muy bienvenidos.
He usado JOpt y lo he encontrado bastante útil: http://jopt-simple.sourceforge.net/
La página principal también proporciona una lista de aproximadamente 8 bibliotecas alternativas, échales un vistazo y elige la que más se adapte a tus necesidades.
Alguien me señaló args4j últimamente, que está basado en anotaciones. ¡Me gusta mucho!
Esta es la biblioteca de análisis de línea de comandos de Google de código abierto como parte del proyecto Bazel. Personalmente, creo que es el mejor y mucho más fácil que la CLI de Apache.
https://github.com/pcj/google-options
maven_jar(
name = "com_github_pcj_google_options",
artifact = "com.github.pcj:google-options:jar:1.0.0",
sha1 = "85d54fe6771e5ff0d54827b0a3315c3e12fdd0c7",
)
dependencies {
compile 'com.github.pcj:google-options:1.0.0'
}
<dependency>
<groupId>com.github.pcj</groupId>
<artifactId>google-options</artifactId>
<version>1.0.0</version>
</dependency>
Cree una clase que amplíe OptionsBase
y defina sus @Option
(s).
package example;
import com.google.devtools.common.options.Option;
import com.google.devtools.common.options.OptionsBase;
import java.util.List;
/**
* Command-line options definition for example server.
*/
public class ServerOptions extends OptionsBase {
@Option(
name = "help",
abbrev = 'h',
help = "Prints usage info.",
defaultValue = "true"
)
public boolean help;
@Option(
name = "host",
abbrev = 'o',
help = "The server host.",
category = "startup",
defaultValue = ""
)
public String host;
@Option(
name = "port",
abbrev = 'p',
help = "The server port.",
category = "startup",
defaultValue = "8080"
)
public int port;
@Option(
name = "dir",
abbrev = 'd',
help = "Name of directory to serve static files.",
category = "startup",
allowMultiple = true,
defaultValue = ""
)
public List<String> dirs;
}
Analiza los argumentos y úsalos.
package example;
import com.google.devtools.common.options.OptionsParser;
import java.util.Collections;
public class Server {
public static void main(String[] args) {
OptionsParser parser = OptionsParser.newOptionsParser(ServerOptions.class);
parser.parseAndExitUponError(args);
ServerOptions options = parser.getOptions(ServerOptions.class);
if (options.host.isEmpty() || options.port < 0 || options.dirs.isEmpty()) {
printUsage(parser);
return;
}
System.out.format("Starting server at %s:%d...\n", options.host, options.port);
for (String dirname : options.dirs) {
System.out.format("\\--> Serving static files at <%s>\n", dirname);
}
}
private static void printUsage(OptionsParser parser) {
System.out.println("Usage: java -jar server.jar OPTIONS");
System.out.println(parser.describeOptions(Collections.<String, String>emptyMap(),
OptionsParser.HelpVerbosity.LONG));
}
}
myexecutable -c file.json -d 42 --outdir ./out
. Y no veo cómo se definen las opciones de descripción corta / larga ... Saludos
Eche un vistazo al proyecto de la CLI de Commons , muchas cosas buenas allí.
Yeap
Creo que estás buscando algo como esto: http://commons.apache.org/cli
La biblioteca CLI de Apache Commons proporciona una API para procesar interfaces de línea de comandos.
Sé que la mayoría de la gente aquí encontrará 10 millones de razones por las que no les gusta mi camino, pero no importa. Me gusta mantener las cosas simples, así que solo separo la clave del valor usando un '=' y las almaceno en un HashMap como este:
Map<String, String> argsMap = new HashMap<>();
for (String arg: args) {
String[] parts = arg.split("=");
argsMap.put(parts[0], parts[1]);
}
Siempre puede mantener una lista con los argumentos que espera, para ayudar al usuario en caso de que haya olvidado un argumento o haya utilizado uno incorrecto ... Sin embargo, si desea demasiadas funciones, esta solución no es para usted de todos modos.
Tal vez estos
Conjunto de análisis de opciones de línea de comandos JArgs para Java : este pequeño proyecto proporciona un conjunto de analizadores de opciones de línea de comandos conveniente, compacto, preempaquetado y exhaustivamente documentado para el uso de programadores Java. Inicialmente, se proporciona un análisis compatible con 'getopt' de estilo GNU.
ritopt, el analizador de opciones definitivo para Java : aunque se han propuesto varios estándares de opciones de línea de comandos, ritopt sigue las convenciones prescritas en el paquete opt.
Puede encontrar este metaartículo de infelicidad interesante como punto de partida:
http://furiouspurpose.blogspot.com/2008/07/command-line-parsing-libraries-for-java.html
Escribí otro: http://argparse4j.sourceforge.net/
Argparse4j es una biblioteca de analizador de argumentos de línea de comandos para Java, basada en el argumento de Python.
Si está familiarizado con gnu getopt, hay un puerto Java en: http://www.urbanophile.com/arenn/hacking/download.htm .
Parece que hay algunas clases que hacen esto:
La aerolínea @ Github se ve bien. Se basa en anotaciones y está tratando de emular estructuras de línea de comandos de Git.
Si ya está utilizando Spring Boot, el análisis de argumentos sale de la caja.
Si desea ejecutar algo después del inicio, implemente la ApplicationRunner
interfaz:
@SpringBootApplication
public class Application implements ApplicationRunner {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Override
public void run(ApplicationArguments args) {
args.containsOption("my-flag-option"); // test if --my-flag-option was set
args.getOptionValues("my-option"); // returns values of --my-option=value1 --my-option=value2
args.getOptionNames(); // returns a list of all available options
// do something with your args
}
}
Su run
método se invocará después de que el contexto se haya iniciado correctamente.
Si necesita acceder a los argumentos antes de activar el contexto de su aplicación, simplemente puede analizar los argumentos de la aplicación manualmente:
@SpringBootApplication
public class Application implements ApplicationRunner {
public static void main(String[] args) {
ApplicationArguments arguments = new DefaultApplicationArguments(args);
// do whatever you like with your arguments
// see above ...
SpringApplication.run(Application.class, args);
}
}
Y finalmente, si necesita acceso a sus argumentos en un bean, simplemente inyecte ApplicationArguments
:
@Component
public class MyBean {
@Autowired
private ApplicationArguments arguments;
// ...
}
Argparse4j es el mejor que he encontrado. Imita la biblioteca argparse de Python, que es muy conveniente y potente.
Si desea algo liviano (tamaño de jarra ~ 20 kb) y fácil de usar, puede probar el analizador de argumentos . Se puede usar en la mayoría de los casos de uso, admite la especificación de matrices en el argumento y no depende de ninguna otra biblioteca. Funciona para Java 1.5 o superior. El siguiente extracto muestra un ejemplo sobre cómo usarlo:
public static void main(String[] args) {
String usage = "--day|-d day --mon|-m month [--year|-y year][--dir|-ds directoriesToSearch]";
ArgumentParser argParser = new ArgumentParser(usage, InputData.class);
InputData inputData = (InputData) argParser.parse(args);
showData(inputData);
new StatsGenerator().generateStats(inputData);
}
Más ejemplos se pueden encontrar aquí
No recomendaría usar Apache Common CLI
biblioteca, ya que no es segura para subprocesos.
Utiliza clases con estado con variables estáticas y métodos para hacer trabajo interno (por ejemplo OptionBuilder
) y solo debe usarse en situaciones de un solo subproceso fuertemente controladas.
Como uno de los comentarios mencionados anteriormente ( https://github.com/pcj/google-options ) sería una buena opción para comenzar.
Una cosa que quiero agregar es:
1) Si se encuentra con algún error de reflexión del analizador, intente utilizar una versión más reciente de la guayaba. en mi caso:
maven_jar(
name = "com_google_guava_guava",
artifact = "com.google.guava:guava:19.0",
server = "maven2_server",
)
maven_jar(
name = "com_github_pcj_google_options",
artifact = "com.github.pcj:google-options:jar:1.0.0",
server = "maven2_server",
)
maven_server(
name = "maven2_server",
url = "http://central.maven.org/maven2/",
)
2) Al ejecutar la línea de comando:
bazel run path/to/your:project -- --var1 something --var2 something -v something
3) Cuando necesite la ayuda de uso, simplemente escriba:
bazel run path/to/your:project -- --help
Para los usuarios de Spring, debemos mencionar también https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/core/env/SimpleCommandLinePropertySource.html y su hermano gemelo https: //docs.spring .io / spring / docs / current / javadoc-api / org / springframework / core / env / JOptCommandLinePropertySource.html (implementación JOpt de la misma funcionalidad). La ventaja en Spring es que puede vincular directamente los argumentos de la línea de comandos a los atributos, aquí hay un ejemplo https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/core/env/ CommandLinePropertySource.html