昨天通過幾個小程式以及Hangout源碼學習了CLI的基本使用,今天就來嘗試翻譯一下CLI的官方使用手冊。 下麵將會通過幾個部分簡單的介紹CLI在應用中的使用場景。 昨天已經聯繫過幾個基本的命令行參數使用場景, "可以參考這裡" 通過使用Apache Commons CLI可以幫助開發者快速構建命令 ...
昨天通過幾個小程式以及Hangout源碼學習了CLI的基本使用,今天就來嘗試翻譯一下CLI的官方使用手冊。
下麵將會通過幾個部分簡單的介紹CLI在應用中的使用場景。
昨天已經聯繫過幾個基本的命令行參數使用場景,可以參考這裡
通過使用Apache Commons CLI可以幫助開發者快速構建命令行啟動模式,並可以快速生成幫助指令,基於用戶啟動參數提供不同的服務。
入門樣例
下麵就舉個例子,比如我想輸入命令:
xxx -t
從而列印出當前的時間。
定義階段——創建選項
首先要創建Options對象,然後添加Option對象.
// create Options object
Options options = new Options();
// add t option
options.addOption("t", false, "display current time");
其中addOption
方法有三個參數:
- 第一個參數是字元串類型,代表命令的參數。
- 第二個參數是Bool型,代表該選項是否需要額外的參數。
- 第三個參數是該選項的描述信息。
上面的例子就代表,t選項不需要參數,它的意思是顯示當前時間
。
解析階段——解析命令行參數
CLI通過CommandLineParser的parse方法解析命令行參數。有好幾種CommandLineParser的實現類,推薦使用的是DefaultParser。看源碼除了這個DefaultParser,其他的都被打上了@Deprecated標記。
除去這個DefaultParser以外,還有一個抽象類實現了CommandLineParser介面——Parser,這個Parser有三個子類:
- BasicParser
- GnuParser
- PosixParser
CommandLineParser parser = new DefaultParser();
CommandLine cmd = parser.parse( options, args);
詢問階段—— 判斷命令行中出現了哪個選項
現在就可以檢查是否存在這個t選項了,首先需要在CommandLine對象中進行查詢。hasOption
方法可以通過選項的名字,判斷命令行是否出現該命令。出現則返回true,否則返回false。
if(cmd.hasOption("t")) {
// print the date and time
}
else {
// print the date
}
全部代碼
public class DateApp {
public static void main(String[] args) {
String[] arg = {"-t"};
// String[] arg = {};
try {
testOption(arg);
} catch (ParseException e) {
e.printStackTrace();
}
}
static void testOption(String[] args) throws ParseException{
Options options = new Options();
options.addOption("t", false, "display current time");
CommandLineParser parser = new DefaultParser();
CommandLine cmd = parser.parse( options, args);
if(cmd.hasOption("t")) {
System.out.println((new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).format(new Date()));
}else {
System.out.println((new SimpleDateFormat("yyyy-MM-dd")).format(new Date()));
}
}
}
進階樣例
下麵這個例子繼承自DateApp,並且提供了根據城市顯示時間和日期的功能。為了實現這個命令,會增加一個c
選項,來添加城市信息。
// add c option
options.addOption("c", true, "country code");
第二個參數這時設置為true,就代表它需要額外的參數。
獲得參數值
CommandLine對象的getOptionValue方法可以獲取到參數的值。
// get c option value
String countryCode = cmd.getOptionValue("c");
if(countryCode == null) {
// print default date
}else {
// print date for country specified by countryCode
}
此時如果只有c選項,沒有參數,就會報錯
org.apache.commons.cli.MissingArgumentException: Missing argument for option: c
at org.apache.commons.cli.DefaultParser.checkRequiredArgs(DefaultParser.java:211)
at org.apache.commons.cli.DefaultParser.parse(DefaultParser.java:125)
at org.apache.commons.cli.DefaultParser.parse(DefaultParser.java:76)
at org.apache.commons.cli.DefaultParser.parse(DefaultParser.java:60)
at hangout.study.InternationalDateApp.testOption(InternationalDateApp.java:29)
at hangout.study.InternationalDateApp.main(InternationalDateApp.java:18)
全部代碼
public class InternationalDateApp {
public static void main(String[] args) {
String[] arg = {"-t","-c","hello"};
// String[] arg = {"-t","-c"};
// String[] arg = {};
try {
testOption(arg);
} catch (ParseException e) {
e.printStackTrace();
}
}
static void testOption(String[] args) throws ParseException{
Options options = new Options();
options.addOption("t", false, "display current time");
options.addOption("c", true, "country code");
CommandLineParser parser = new DefaultParser();
CommandLine cmd = parser.parse( options, args);
if(cmd.hasOption("t")) {
System.out.println((new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).format(new Date())+" in "+cmd.getOptionValue("c"));
}else {
System.out.println((new SimpleDateFormat("yyyy-MM-dd")).format(new Date()));
}
}
}
此時運行代碼,則會正確輸出信息:
2016-06-23 21:18:50 in hello
Ant樣例
下麵舉一個Ant的樣例,下麵是Ant輸出的幫助信息
ant [options] [target [target2 [target3] ...]]
Options:
-help print this message
-projecthelp print project help information
-version print the version information and exit
-quiet be extra quiet
-verbose be extra verbose
-debug print debugging information
-emacs produce logging information without adornments
-logfile <file> use given file for log
-logger <classname> the class which is to perform logging
-listener <classname> add an instance of class as a project listener
-buildfile <file> use given buildfile
-D<property>=<value> use value for given property
-find <file> search for buildfile towards the root of the
filesystem and use it
使用Bool選項創建
Option help = new Option( "help", "print this message" );
Option projecthelp = new Option( "projecthelp", "print project help information" );
Option version = new Option( "version", "print the version information and exit" );
Option quiet = new Option( "quiet", "be extra quiet" );
Option verbose = new Option( "verbose", "be extra verbose" );
Option debug = new Option( "debug", "print debugging information" );
Option emacs = new Option( "emacs","produce logging information without adornments" );
也可以使用OptionBuilder構建選項:
Option logfile = OptionBuilder.withArgName( "file" )
.hasArg()
.withDescription( "use given file for log" )
.create( "logfile" );
Option logger = OptionBuilder.withArgName( "classname" )
.hasArg()
.withDescription( "the class which it to perform "+ "logging" )
.create( "logger" );
Option listener = OptionBuilder.withArgName( "classname" )
.hasArg()
.withDescription( "add an instance of class as "+ "a project listener" )
.create( "listener");
Option buildfile = OptionBuilder.withArgName( "file" )
.hasArg()
.withDescription( "use given buildfile" )
.create( "buildfile");
Option find = OptionBuilder.withArgName( "file" )
.hasArg()
.withDescription( "search for buildfile towards the "+ "root of the filesystem and use it" )
.create( "find" );
最後一個OptionBuilder創建帶有參數名稱的選項:
Option property = OptionBuilder.withArgName( "property=value" )
.hasArgs(2)
.withValueSeparator()
.withDescription( "use value for given property" )
.create( "D" );
通過上面的方式定義的屬性,可以通過CommandLine對象的getOptionProperties("D")方法獲得。
定義階段——創建選項
Options options = new Options();
options.addOption( help );
options.addOption( projecthelp );
options.addOption( version );
options.addOption( quiet );
options.addOption( verbose );
options.addOption( debug );
options.addOption( emacs );
options.addOption( logfile );
options.addOption( logger );
options.addOption( listener );
options.addOption( buildfile );
options.addOption( find );
options.addOption( property );
解析階段——創建解析器
跟前面類似,創建CommandLineParser解析器,返回CommandLine對象,用於查詢選項參數。
public static void main( String[] args ) {
// create the parser
CommandLineParser parser = new DefaultParser();
try {
// parse the command line arguments
CommandLine line = parser.parse( options, args );
}
catch( ParseException exp ) {
// oops, something went wrong
System.err.println( "Parsing failed. Reason: " + exp.getMessage() );
}
}
詢問階段——查詢命令行參數
通過hasOption選項判斷是否包含某個選項參數:
// has the buildfile argument been passed?
if( line.hasOption( "buildfile" ) ) {
// initialise the member variable
this.buildfile = line.getOptionValue( "buildfile" );
}
創建幫助信息
一般命令行工具都有help幫助提示,即輸入-h命令,就會輸出所有的命令參數。CLI提供給我們快捷輸出幫助信息的工具——HelpFormatter。
// automatically generate the help statement
HelpFormatter formatter = new HelpFormatter();
formatter.printHelp( "ant", options );
當執行到此處時,就會輸出相應的幫助信息
usage: ant
-D <property=value> use value for given property
-buildfile <file> use given buildfile
-debug print debugging information
-emacs produce logging information without adornments
-file <file> search for buildfile towards the root of the
filesystem and use it
-help print this message
-listener <classname> add an instance of class as a project listener
-logger <classname> the class which it to perform logging
-projecthelp print project help information
-quiet be extra quiet
-verbose be extra verbose
-version print the version information and exit
全部代碼
public class AntExample {
public static void main(String[] args) {
String[] arg = {"-help"};
testOption(arg);
}
@SuppressWarnings({ "deprecation", "static-access" })
static void testOption(String[] args){
Option help = new Option( "help", "print this message" );
Option projecthelp = new Option( "projecthelp", "print project help information" );
Option version = new Option( "version", "print the version information and exit" );
Option quiet = new Option( "quiet", "be extra quiet" );
Option verbose = new Option( "verbose", "be extra verbose" );
Option debug = new Option( "debug", "print debugging information" );
Option emacs = new Option( "emacs","produce logging information without adornments" );
Option logfile = OptionBuilder.withArgName( "file" )
.hasArg()
.withDescription( "use given file for log" )
.create( "logfile" );
Option logger = OptionBuilder.withArgName( "classname" )
.hasArg()
.withDescription( "the class which it to perform "+ "logging" )
.create( "logger" );
Option listener = OptionBuilder.withArgName( "classname" )
.hasArg()
.withDescription( "add an instance of class as "+ "a project listener" )
.create( "listener");
Option buildfile = OptionBuilder.withArgName( "file" )
.hasArg()
.withDescription( "use given buildfile" )
.create( "buildfile");
Option find = OptionBuilder.withArgName( "file" )
.hasArg()
.withDescription( "search for buildfile towards the " + "root of the filesystem and use it" )
.create( "find" );
Option property = OptionBuilder.withArgName( "property=value" )
.hasArgs(2)
.withValueSeparator()
.withDescription( "use value for given property" )
.create( "D" );
Options options = new Options();
options.addOption( help );
options.addOption( projecthelp );
options.addOption( version );
options.addOption( quiet );
options.addOption( verbose );
options.addOption( debug );
options.addOption( emacs );
options.addOption( logfile );
options.addOption( logger );
options.addOption( listener );
options.addOption( buildfile );
options.addOption( find );
options.addOption( property );
CommandLineParser parser = new DefaultParser();
try {
CommandLine line = parser.parse( options, args );
if( line.hasOption( "buildfile" ) ) {
System.out.println(line.getOptionValue( "buildfile" ));
}
if( line.hasOption("help")){
HelpFormatter formatter = new HelpFormatter();
formatter.printHelp( "ant", options );
}
}catch( ParseException exp ) {
System.err.println( "Parsing failed. Reason: " + exp.getMessage() );
}
}
}
運行後得到下麵的輸出信息:
usage: ant
-buildfile <file> use given buildfile
-D <property=value> use value for given property
-debug print debugging information
-emacs produce logging information without adornments
-find <file> search for buildfile towards the root of the
filesystem and use it
-help print this message
-listener <classname> add an instance of class as a project listener
-logfile <file> use given file for log
-logger <classname> the class which it to perform logging
-projecthelp print project help information
-quiet be extra quiet
-verbose be extra verbose
-version print the version information and exit
如果想在輸出信息中加入參數列表,也可以在printHelp加入第三個參數true,formatter.printHelp( "ant", options, true);
usage: ant [-buildfile <file>] [-D <property=value>] [-debug] [-emacs]
[-find <file>] [-help] [-listener <classname>] [-logfile <file>]
[-logger <classname>] [-projecthelp] [-quiet] [-verbose] [-version]
-buildfile <file> use given buildfile
-D <property=value> use value for given property
-debug print debugging information
-emacs produce logging information without adornments
-find <file> search for buildfile towards the root of the
filesystem and use it
-help print this message
-listener <classname> add an instance of class as a project listener
-logfile <file> use given file for log
-logger <classname> the class which it to perform logging
-projecthelp print project help information
-quiet be extra quiet
-verbose be extra verbose
-version print the version information and exit
LS樣例
這個例子模擬了Linux下的命令行使用幫助:
全部代碼:
public class LSExample {
public static void main(String[] args) {
String[] arg = new String[]{ "--block-size=10" };
testOption(arg);
}
static void testOption(String[] args){
CommandLineParser parser = new DefaultParser();
// create the Options
Options options = new Options();
options.addOption( "a", "all", false, "do not hide entries starting with ." );
options.addOption( "A", "almost-all", false, "do not list implied . and .." );
options.addOption( "b", "escape", false, "print octal escapes for nongraphic "
+ "characters" );
options.addOption( OptionBuilder.withLongOpt( "block-size" )
.withDescription( "use SIZE-byte blocks" )
.hasArg()
.withArgName("SIZE")
.create() );
options.addOption( "B", "ignore-backups", false, "do not list implied entried "
+ "ending with ~");
options.addOption( "c", false, "with -lt: sort by, and show, ctime (time of last "
+ "modification of file status information) with "
+ "-l:show ctime and sort by name otherwise: sort "
+ "by ctime" );
options.addOption( "C", false, "list entries by columns" );
try {
CommandLine line = parser.parse( options, args );
if( line.hasOption( "block-size" ) ) {
System.out.println( line.getOptionValue( "block-size" ) );
}
}
catch( ParseException exp ) {
System.out.println( "Unexpected exception:" + exp.getMessage() );
}
}
}
輸出可以得到下麵的信息:
10
usage: ls
-a,--all do not hide entries starting with .
-A,--almost-all do not list implied . and ..
-b,--escape print octal escapes for nongraphic characters
-B,--ignore-backups do not list implied entried ending with ~
--block-size <SIZE> use SIZE-byte blocks
-c with -lt: sort by, and show, ctime (time of last
modification of file status information) with
-l:show ctime and sort by name otherwise: sort
by ctime
-C list entries by columns