web-dev-qa-db-fra.com

Comment analyser les arguments de ligne de commande en Java?

Quel est le bon moyen d’analyser les arguments de ligne de commande en Java?

532
lindelof

Vérifiez ces:

Ou roulez les vôtres:


Par exemple, voici comment vous utilisez commons-cli pour analyser 2 arguments de chaîne:

_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);

    }

}
_

utilisation en ligne de commande:

_$> 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
_
357
Vinko Vrsalovic

Jetez un coup d'œil au plus récent JCommander .

Je l'ai créé. Je suis heureux de recevoir des questions ou des demandes de fonctionnalités.

299
Cedric Beust
224
lexicalscope

J'ai utilisé JOpt et je l'ai trouvé assez pratique: http://jopt-simple.sourceforge.net/

La page d'accueil fournit également une liste d'environ 8 bibliothèques alternatives, consultez-les et choisissez celle qui convient le mieux à vos besoins.

22
GaryF

Quelqu'un m'a indiqué args4j dernièrement, qui est basé sur des annotations. J'aime vraiment ça!

20
André

Acheter ou construire?

De nombreuses petites applications ressemblant à des utilitaires lancent probablement leur propre analyse en ligne de commande pour éviter la dépendance externe supplémentaire.

picocli peut être intéressant. Il est conçu pour être inclus en tant que source en tant qu'alternative plus simple à l'ombrage de bocaux dans un uberjar.

Une autre fonctionnalité qui pourrait vous plaire est son aide à l’utilisation colorisée.

Minimal usage help with ANSI colors

Caractéristiques de l'analyseur:

  • Basé sur les annotations: l'analyse est une ligne de code
  • Tout fortement typé - options de ligne de commande ainsi que paramètres de position
  • Options courtes de cluster POSIX (<command> -xvfInputFile ainsi que <command> -x -v -f InputFile)
  • Un modèle d'arité qui permet un nombre minimal, maximal et variable de paramètres, par exemple, "1..*", "3..5"
  • Sous-commandes (peuvent être imbriquées à une profondeur arbitraire)
  • Fonctionne avec Java 5 et supérieur

Le message d'aide à l'utilisation est facile à personnaliser avec des annotations (sans programmation). Par exemple:

Extended usage help message ( source )

Je n'ai pas pu résister à l'ajout d'une capture d'écran supplémentaire pour montrer les messages d'aide d'utilisation possibles. L’aide à l’utilisation est le visage de votre application, alors soyez créatif et amusez-vous!

picocli demo

Disclaimer: j'ai créé picocli. Vos commentaires ou questions sont les bienvenus.

12
Remko Popma

Il s'agit de la bibliothèque d'analyse en ligne de commande de Google en source ouverte faisant partie du projet Bazel. Personnellement, je pense que c'est la meilleure solution, et beaucoup plus facile que Apache CLI.

https://github.com/pcj/google-options

Installation

Bazel

maven_jar(
    name = "com_github_pcj_google_options",
    artifact = "com.github.pcj:google-options:jar:1.0.0",
    sha1 = "85d54fe6771e5ff0d54827b0a3315c3e12fdd0c7",
)

Gradle

dependencies {
  compile 'com.github.pcj:google-options:1.0.0'
}

Maven

<dependency>
  <groupId>com.github.pcj</groupId>
  <artifactId>google-options</artifactId>
  <version>1.0.0</version>
</dependency>

Usage

Créez une classe qui étend OptionsBase et définit votre @Option.

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;

}

Analyser les arguments et les utiliser.

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));
  }

}

https://github.com/pcj/google-options

9
Paul

Jetez un coup d'œil au projet Commons CLI , plein de bonnes choses là-dedans.

8
Marc Novakowski

Yeap.

Je pense que vous cherchez quelque chose comme ceci: http://commons.Apache.org/cli

La bibliothèque Apache Commons CLI fournit une API pour le traitement des interfaces de ligne de commande.

8
OscarRyz

Peut-être que ces

7
mepcotterell

Vous pourriez trouver ce méta-article sur le malheur intéressant comme point de départ:

http://furiouspurpose.blogspot.com/2008/07/command-line-parsing-libraries-for-Java.html

6
Alex Miller

J'ai écrit un autre: http://argparse4j.sourceforge.net/

Argparse4j est une bibliothèque d'analyse syntaxique d'arguments de ligne de commande pour Java, basée sur argparse de Python.

5
5
Ray Tayek

airline @ Github a l'air bien. Il est basé sur des annotations et tente d'émuler les structures de ligne de commande Git.

4
cthiebaud

Je sais que la plupart des gens ici vont trouver 10 millions de raisons pour lesquelles ils n'aiment pas mon chemin, mais tant pis. J'aime garder les choses simples, alors je sépare simplement la clé de la valeur en utilisant un '=' et les stocke dans un HashMap comme ceci:

Map<String, String> argsMap = new HashMap<>();
for (String arg: args) {
    String[] parts = arg.split("=");
    argsMap.put(parts[0], parts[1]);
} 

Vous pouvez toujours conserver une liste des arguments que vous attendez, pour aider l'utilisateur s'il oublie un argument ou utilise un argument erroné ... Toutefois, si vous voulez trop de fonctionnalités, cette solution ne vous convient pas.

3
John Koumarelas

Argparse4j est le meilleur que j'ai trouvé. Il imite la bibliothèque argparse de Python, qui est très pratique et puissant.

2
Trismegistos

Si vous voulez quelque chose de léger (taille de jar ~ 20 kb) et simple à utiliser, vous pouvez essayer argument-parser . Il peut être utilisé dans la plupart des cas d'utilisation, prend en charge la spécification de tableaux dans l'argument et ne dépend d'aucune autre bibliothèque. Cela fonctionne pour Java 1.5 ou supérieur. L'extrait ci-dessous montre un exemple d'utilisation:

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);
}

Plus d'exemples peuvent être trouvés ici

2
Himanshu Shekhar

Je ne recommanderais pas d'utiliser la bibliothèque Apache Common CLI, car elle n'est pas threadsafe. Il utilise des classes avec état avec des variables statiques et des méthodes pour effectuer un travail interne (par exemple, OptionBuilder) et ne doit être utilisé que dans des situations à contrôle unique fortement threadées.

2
Jakub

Si vous utilisez déjà Spring Boot, l'analyse des arguments est prête à l'emploi.

Si vous souhaitez exécuter quelque chose après le démarrage, implémentez l'interface ApplicationRunner:

@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
  }
}

Votre méthode run sera invoquée une fois le contexte démarré avec succès.

Si vous avez besoin d'accéder aux arguments avant vous lancez le contexte de votre application, vous pouvez simplement analyser les arguments de l'application manuellement:

@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);
  }

}

Et enfin, si vous avez besoin d'accéder à vos arguments dans un haricot, il suffit d'injecter la ApplicationArguments:

@Component
public class MyBean {

   @Autowired
   private ApplicationArguments arguments;

   // ...
}
1
Stefan Haberl

Comme l’un des commentaires mentionnés plus tôt ( https://github.com/pcj/google-options ) serait un bon choix pour commencer.

Une chose que je veux ajouter est la suivante:

1) Si vous rencontrez une erreur de réflexion de l’analyseur, essayez d’utiliser une version plus récente de la goyave. dans mon cas:

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) Lors de l'exécution de la ligne de commande:

bazel run path/to/your:project -- --var1 something --var2 something -v something

3) Lorsque vous avez besoin d'aide pour l'utilisation, tapez simplement:

bazel run path/to/your:project -- --help
0
stevens