In the process of working on one project, it became necessary to develop a console application for remote access to the system. I took this for the first time on such a scale, before everything was on the windows or if the console, then the exact number, type and order of the transmitted parameters are known. And here there was a need for a large number of commands, each with its own parameters, or even without them, respectively, to ensure flexibility, there was a need for a parser, passed parameters.
In order not to reinvent the wheel, I decided to take a ready-made library. The choice stopped at
commons-cli , we managed to find a couple of examples for it and using it seemed not very difficult.
As it turned out, there are not so many examples and they cover only the basic needs of the developer. I'll try to fill this gap with my own explanations.
So, let's begin. Commons-cli is based on the notion of an option. In order to immediately clarify, try to determine the terminology. Consider this line:
')
Text.exe –l login ––password 123456
The test.exe program is called using the l option, which takes the string "login" as an argument and using the password option, with an argument as the string "123456". It is not difficult to guess that the program requires authentication, the l option is responsible for the login, and the password option is itself a password. For simplicity, it is possible to consider the pair “option, argument” in the classical way “parameter = value”.
By the way, the entry form with the “=” sign is quite acceptable when using commons-cli.
Options can be without arguments at all or there can be more than one arguments. If an option name consists of 1 letter, then it is preceded by a “-” (let's call it, by a simple “dash”). If the option name consists of 2 or more letters, then it is necessary to double the “dash”, as with the password option.
Deal with the terminology, you can go directly to the code. So it all starts with options. Create an option:
Option option = new Option("l", "login", true, "Login");
The spacecraft in this case takes 4 parameters: a short form of the option (single letter option), a long form of the option, a flag indicating the presence of parameters and a text explanation of the option. We could specify only single-letter options of the option or only an extended view of the option, in each of these cases the designer would take 3 parameters, but not specify either a multi-letter or single-letter option, you must specify at least one. Then you need to determine how this option will work with arumenty. Like that:
option.setArgs(1);
It seems that from the comments to the code everything should be clear. If we need an option with no arguments (flag option), then setArgs (0). After creating an option, you need to add it to the Options object.
Options posixOptions = new Options(); posixOptions.addOption(option);
Now you need to create a command line parser and provide it with the necessary information for work:
CommandLineParser cmdLinePosixParser = new PosixParser();
To begin with we create a parser, a full-fledged parser in commons-cli 2 - Posix parser and GNU parser. Frankly, I didn’t go into their differences, but after a quick inspection I liked the Posix-parser (regulated by the
Posix standard, the system supporting this standard will work accordingly for all). , and the actual string with the parameters that were transferred to your program when it started (by itself, the standard args [] array must be separated into one line by separating the elements with spaces). The parse result will be returned to the commandLine object.
Now you need to execute the commands received, this is done like this:
if (commandLine.hasOption(“l”)) {
As you can see, working with commons-cli is quite simple. In addition, this library will take care of the output of help on the use of the program, not completely, but it will ease a lot:
public static void printHelp( final Options options, final int printedRowWidth, final String header, final String footer, final int spacesBeforeOption, final int spacesBeforeOptionDescription, final boolean displayUsage, final OutputStream out) { final String commandLineSyntax = "java test.jar";
To make everything clear, I will give an example of calling this method:
printHelp( posixOptions,
Perhaps here everything is clear, except for the term “usage string”. I will give an example an example from which it will become clear how to use this parameter. If true, the output will be something like this:
usage: java test.jar [-l] [-h]
If false, the output will be as follows:
usage: java test.jar
I think the difference is clear.
The last is groups of options. For example, there are two options -a and -b, they are mutually exclusive, that is, they cannot be specified at the same time. For such a case, groups of options are created:
OptionGroup optionGroup = new OptionGroup(); optionGroup.addOption(new Option("a", true, "A option"); optionGroup.addOption(new Option("b", true, "B option"); posixOptions.addOptionGroup(optionGroup);
Everything is pretty simple too.
In general, the library left a good impression on the use, but very quickly it began to be missed. The current version of the library 1.2, while there is a development of a completely new version 2.0 - in fact, according to the description of api version 2.0, we can say that this version should satisfy most of the demands placed on the cli libraries.
The advantages of commons-cli are:
- ease of use
- option groups
- long and short option notation (-l, --login)
- possibility to parse options of the following type -ab, when there are two options -a, -b
Cons (from their own needs, and of course there are more of them):
- There is no possibility to create subcommands (as in git there are commands branch, status, etc. with their options)
- not very convenient work with option arguments, if there are more than 1
As a result, for a simple cli is a great solution, something more serious is to look for alternatives or wait for version 2.0.
Links in the article:
UPD. At the prompt,
nord_ua corrected the reference to the Posix standard command line.
Corrected typos and added a link to commons-cli. Thanks
nik_lazarev and
FractalizeR .