Apache Commons CLI官方文檔翻譯 —— 快速構建命令行啟動模式

来源:http://www.cnblogs.com/xing901022/archive/2016/06/23/5612328.html
-Advertisement-
Play Games

昨天通過幾個小程式以及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

參考

我的前一天總結
Apache Common CLI官方文檔


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 今天用Python提取了Linux內核源代碼的目錄樹結構,沒有怎麼寫過腳本程式,我居然折騰了2個小時,先是如何枚舉出給定目錄下的所有文件和文件夾,os.walk可以實現列舉,但是os.walk是只給出目錄名和文件名,而沒有絕對路徑。使用os.path.listdir可以達到這個目的,然後是創建目錄, ...
  • 上一文只研究了JImage類,今天繼續其他常用的joomla內置類,個人是從常用角度來寫的,如果PHP本身函數比起Joomla內置類用起來更方便的,我就濾過不說,如果你實在想用,自己去查吧,個人覺得,無論多優秀的方法,如果PHP自帶函數也能很好解決,那麼用PHP內置函數是最好的,學習PHP首先就是學 ...
  • C++11支持range-based for迴圈。這是一個很方便的特性,能省挺多代碼。以下代碼就能很方便的遍歷vector中的元素,並列印出來: 1 2 3 4 5 6 7 8 std::vector<int> int_vec; int_vec.push_back(1); int_vec.push_ ...
  • 說到java中的重載和覆蓋呢,大家都很熟悉了吧,但是呢我今天就要寫這個。 本文主題: 一.什麼是重載 二.什麼是覆蓋 三.兩者之間的區別 重載(overload): 在一個類中,如果出現了兩個或者兩個以上的同名函數,只要它們的參數的個數,或者參數的類型不同,即可稱之為該函數重載了。 即當函數同名時, ...
  • 本文將介紹常用的線程間通信工具CountDownLatch、CyclicBarrier和Phaser的用法,並結合實例介紹它們各自的適用場景及相同點和不同點。 ...
  • 解題思路: 插入操作在stack1中進行,刪除操作在stack2中進行,如果stack2為空,則將stack1中的所有元素轉移到stack2中。 ...
  • 字元串APPAPT中包含了兩個單詞“PAT”,其中第一個PAT是第2位(P),第4位(A),第6位(T);第二個PAT是第3位(P),第4位(A),第6位(T)。 現給定字元串,問一共可以形成多少個PAT? 輸入格式: 輸入只有一行,包含一個字元串,長度不超過105,只包含P、A、T三種字母。 輸出 ...
  • Any 前面已經有兩次提到過:在scala中,Any類是所有類的超類。 Any有兩個子類:AnyVal和AnyRef。對應Java直接類型的scala封裝類,如Int、Double等,AnyVal是它們的基類;對應引用類型,AnyRef是它們的基類。 scala中,所有類的關係可以用下麵這張圖大致描... ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...