Was ist eine gute Möglichkeit, Befehlszeilenargumente in Java zu analysieren?
How to parse java command line arguments?. Aber niemand möchte wirklich Code schreiben, um dies zu tun, sondern ein Werkzeug verwenden. Aber die Suche nach Werkzeugen und
Was ist eine gute Möglichkeit, Befehlszeilenargumente in Java zu analysieren?
How to parse java command line arguments?. Aber niemand möchte wirklich Code schreiben, um dies zu tun, sondern ein Werkzeug verwenden. Aber die Suche nach Werkzeugen und
Antworten:
Guck dir diese an:
Oder rollen Sie Ihre eigenen:
Zum Beispiel ist dies , wie Sie verwenden commons-clizwei String - Argumente zu analysieren:
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);
}
}
Verwendung über die Befehlszeile:
$> 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
Schauen Sie sich den neueren JCommander an .
Ich habe es geschaffen. Ich freue mich über Fragen oder Feature-Anfragen.
Ich habe versucht, eine Liste von Java CLI-Parsern zu führen .
Es ist 2020, Zeit, es besser zu machen als Commons CLI ... :-)
Sollten Sie Ihren eigenen Java-Befehlszeilenparser erstellen oder eine Bibliothek verwenden?
Viele kleine Utility-ähnliche Anwendungen führen wahrscheinlich eine eigene Befehlszeilenanalyse durch, um die zusätzliche externe Abhängigkeit zu vermeiden. Picocli kann eine interessante Alternative sein.
Picocli ist eine moderne Bibliothek und ein Framework, mit dem Sie mühelos leistungsstarke, benutzerfreundliche und GraalVM-fähige Befehlszeilen-Apps erstellen können. Es befindet sich in einer Quelldatei, sodass Apps es als Quelle einschließen können, um das Hinzufügen einer Abhängigkeit zu vermeiden.
Es unterstützt Farben, automatische Vervollständigung, Unterbefehle und mehr. Geschrieben in Java, verwendbar von Groovy, Kotlin, Scala usw.
Eigenschaften:
<command> -xvfInputFilesowie<command> -x -v -f InputFile )"1..*"."3..5"Die Verwendungshilfemeldung kann einfach mit Anmerkungen angepasst werden (ohne Programmierung). Zum Beispiel:
( Quelle )
Ich konnte nicht widerstehen, einen weiteren Screenshot hinzuzufügen, um zu zeigen, welche Verwendungshilfemeldungen möglich sind. Die Hilfe zur Verwendung ist das Gesicht Ihrer Anwendung. Seien Sie also kreativ und haben Sie Spaß!
Haftungsausschluss: Ich habe picocli erstellt. Feedback oder Fragen sind sehr willkommen.
Ich habe JOpt verwendet und fand es ziemlich praktisch: http://jopt-simple.sourceforge.net/
Auf der Startseite finden Sie außerdem eine Liste mit ca. 8 alternativen Bibliotheken. Schauen Sie sich diese an und wählen Sie die aus, die Ihren Anforderungen am besten entspricht.
Jemand hat mich in letzter Zeit auf args4j hingewiesen, das auf Anmerkungen basiert. Ich mag es wirklich!
Dies ist Googles Befehlszeilen-Analysebibliothek, die im Rahmen des Bazel-Projekts als Open-Source-Bibliothek bereitgestellt wird. Persönlich denke ich, dass es das beste ist und viel einfacher als Apache CLI.
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>
Erstellen Sie eine Klasse, OptionsBasedie Ihre @Option(n) erweitert und definiert .
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;
}
Analysieren Sie die Argumente und verwenden Sie sie.
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. Und ich sehe nicht, wie Sie kurze / lange / Beschreibungsoptionen definieren ... Cheers
Schauen Sie sich das Commons CLI- Projekt an, viele gute Sachen drin.
Ja.
Ich denke, Sie suchen nach so etwas: http://commons.apache.org/cli
Die Apache Commons CLI-Bibliothek bietet eine API für die Verarbeitung von Befehlszeilenschnittstellen.
Ich weiß, dass die meisten Leute hier 10 Millionen Gründe finden werden, warum sie meinen Weg nicht mögen, aber egal. Ich mag es, die Dinge einfach zu halten, also trenne ich den Schlüssel einfach mit einem '=' vom Wert und speichere sie in einer HashMap wie folgt:
Map<String, String> argsMap = new HashMap<>();
for (String arg: args) {
String[] parts = arg.split("=");
argsMap.put(parts[0], parts[1]);
}
Sie können jederzeit eine Liste mit den erwarteten Argumenten führen, um dem Benutzer zu helfen, falls er ein Argument vergessen oder ein falsches verwendet hat. Wenn Sie jedoch zu viele Funktionen wünschen, ist diese Lösung ohnehin nichts für Sie.
Vielleicht diese
JArgs-Parsing-Suite für Befehlszeilenoptionen für Java - Dieses winzige Projekt bietet eine praktische, kompakte, vorgefertigte und umfassend dokumentierte Suite von Parsern für Befehlszeilenoptionen für Java-Programmierer. Zunächst wird eine Analyse angeboten, die mit 'getopt' im GNU-Stil kompatibel ist.
ritopt, der ultimative Optionsparser für Java - Obwohl mehrere Befehlszeilenoptionsstandards festgelegt wurden, folgt ritopt den im opt-Paket vorgeschriebenen Konventionen.
Vielleicht finden Sie diesen Meta-Artikel des Unglücks als Ausgangspunkt interessant:
http://furiouspurpose.blogspot.com/2008/07/command-line-parsing-libraries-for-java.html
Ich habe einen anderen geschrieben: http://argparse4j.sourceforge.net/
Argparse4j ist eine Befehlszeilenargument-Parser-Bibliothek für Java, die auf Pythons Argparse basiert.
Wenn Sie mit gnu getopt vertraut sind, gibt es einen Java-Port unter: http://www.urbanophile.com/arenn/hacking/download.htm .
Es scheint einige Klassen zu geben, die dies tun:
Airline @ Github sieht gut aus. Es basiert auf Anmerkungen und versucht, Git-Befehlszeilenstrukturen zu emulieren.
Wenn Sie Spring Boot bereits verwenden, ist die Argumentanalyse sofort einsatzbereit.
Wenn Sie nach dem Start etwas ausführen möchten, implementieren Sie die ApplicationRunnerSchnittstelle:
@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
}
}
Ihre run Methode wird aufgerufen, nachdem der Kontext erfolgreich gestartet wurde.
Wenn Sie Zugriff auf die Argumente benötigen, bevor Sie Ihren Anwendungskontext starten, können Sie die Anwendungsargumente einfach manuell analysieren:
@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);
}
}
Und schließlich, wenn Sie Zugriff auf Ihre Argumente in einer Bean benötigen, fügen Sie einfach Folgendes ein ApplicationArguments:
@Component
public class MyBean {
@Autowired
private ApplicationArguments arguments;
// ...
}
Argparse4j ist das Beste, was ich gefunden habe. Es ahmt Pythons Argparse-Bibliothek nach, die sehr praktisch und mächtig ist.
Wenn Sie etwas Leichtes (JAR-Größe ~ 20 KB) und eine einfache Verwendung wünschen, können Sie den Argument-Parser ausprobieren . Es kann in den meisten Anwendungsfällen verwendet werden, unterstützt die Angabe von Arrays im Argument und ist von keiner anderen Bibliothek abhängig. Es funktioniert für Java 1.5 oder höher. Der folgende Auszug zeigt ein Beispiel für die Verwendung:
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);
}
Weitere Beispiele finden Sie hier
Ich würde die Verwendung der Apache Common CLIBibliothek nicht empfehlen , da sie nicht threadsicher ist.
Es verwendet statusbehaftete Klassen mit statischen Variablen und Methoden für interne Arbeiten (z. B. OptionBuilder) und sollte nur in stark kontrollierten Situationen mit einem Thread verwendet werden.
Wie einer der zuvor erwähnten Kommentare ( https://github.com/pcj/google-options ) wäre zunächst eine gute Wahl.
Eine Sache, die ich hinzufügen möchte, ist:
1) Wenn Sie auf einen Parser-Reflexionsfehler stoßen, versuchen Sie bitte, eine neuere Version der Guave zu verwenden. in meinem Fall:
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) Beim Ausführen der Befehlszeile:
bazel run path/to/your:project -- --var1 something --var2 something -v something
3) Wenn Sie Hilfe bei der Verwendung benötigen, geben Sie einfach Folgendes ein:
bazel run path/to/your:project -- --help
Für Spring-Benutzer sollten wir auch https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/core/env/SimpleCommandLinePropertySource.html und seinen Zwillingsbruder https: //docs.spring erwähnen .io / spring / docs / current / javadoc-api / org / springframework / core / env / JOptCommandLinePropertySource.html (JOpt-Implementierung derselben Funktionalität). Der Vorteil in Spring ist, dass Sie die Befehlszeilenargumente direkt an Attribute binden können. Hier finden Sie ein Beispiel: https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/core/env/ CommandLinePropertySource.html