日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

使用 Apache Commons CLI 开发命令行工具

發布時間:2024/4/17 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使用 Apache Commons CLI 开发命令行工具 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

http://www.ibm.com/developerworks/cn/java/j-lo-commonscli/index.html

使用 Apache Commons CLI 開發命令行工具

楊 暉, 資深軟件工程師, IBM 楊暉,目前就職于 IBM 中國系統與科技研發中心(CSTL),是一名資深軟件工程師,他目前主要從事 IBM System Director 和存儲配置管理軟件(Storage Configuration Manager)的開發。另外,他對 Common Information Model (CIM)和其他開源項目也比較感興趣。 羅 文剛, 軟件工程師, IBM 羅文剛,目前就職于 IBM 中國系統與科技研發中心(CSTL),是一名軟件工程師,他目前主要從事 IBM System Director 的開發。

簡介:?雖然各種人機交互技術飛速發展,但最傳統的命令行模式依然被廣泛應用于各個領域:從編譯代碼到系統管理,命令行因其簡潔高效而備受寵愛。各種工具和系統都提供了詳盡的使用手冊,有些還提供示例說明如何二次開發。然而關于如何開發一個易用、強壯的命令行工具的文章卻很少。本文將結合 Apache Commons CLI,通過一個完整的例子展示如何準備、開發、測試一個命令行工具。希望本文對有相關需求的讀者能有所幫助。

平均分 (11個評分)
為本文評分

基于 Apache Commons CLI 的命令行設計

通常情況下命令行處理有三個步驟:定義,解析和詢問階段。本章節將依次解釋這三個步驟,并將結合實例來討論如何通過 Apache Commons CLI 來實現它們。由于本文作者一直從事和存儲相關的工作,所以我們將設計一個如何向 Server 中添加 / 刪除存儲數據源的 CLI。

以下是具體應用場景,用戶可以通過以下方式來添加/刪除通過 CIM (Common Information Model) Server 管理的存儲數據源:

  • 添加通過 CIM Server 管理的存儲,例如添加 IBM DS Series,命令行設計如下:
    mkdatasource [-h | -? | --help] mkdatasource [-t string] [-i string] [-p string] [-u string] [-w string] [-n string]-h Lists short help -t Sets the HTTP communication protocol for CIM connection -i Sets the IPv4 address of the device -p Sets the HTTP communication port for CIM connection -u Specifies the user ID for the data source connection -w Specifies the password for the data source connection -n Identifies the namespace of the CIM connection Examples: Add CIM Storage Subsystem mkdatasource –t http –i 9.3.194.11 –p 5988 –u admin –w admin –n root/lsiarray13

  • 刪除通過 CIM Server 管理的存儲,例如刪除 IBM DS Series,命令行設計如下:
    rmdatasource [-h | -? | --help] rmdatasource [-t string] [-i string] [-p string] -h Lists short help -t Sets the HTTP communication protocol for CIM connection -i Sets the IPv4 address of the device -p Sets the HTTP communication port for CIM connection Examples: Remove CIM Storage Subsystem rmdatasource –t http –i 9.3.194.11 –p 5988

  • CLI 定義階段

    每一條命令行都必須定義一組參數,它們被用來定義應用程序的接口。Apache Commons CLI 使用 Options 這個類來定義和設置參數,它是所有 Option 實例的容器。在 CLI 中,目前有兩種方式來創建 Options,一種是通過構造函數,這是最普通也是最為大家所熟知的一種方式;另外一種方法是通過 Options 中定義的工廠方式來實現。

    CLI 定義階段的目標結果就是創建 Options 實例。

    根據上面給出的具體命令行設計,我們可以用如下代碼片段為添加數據源操作定義 Options:


    清單 1. 定義 Options 代碼片段
    // 創建 Options 對象Options options = new Options(); // 添加 -h 參數options.addOption("h", false, "Lists short help"); // 添加 -t 參數options.addOption("t", true, "Sets the HTTP communication protocol for CIM connection");

    其中 addOption() 方法有三個參數,第一個參數設定這個 option 的單字符名字,第二個參數指明這個 option 是否需要輸入數值,第三個參數是對這個 option 的簡要描述。在這個代碼片段中,第一個參數只是列出幫助文件,不需要用戶輸入任何值,而第二個參數則是需要用戶輸入 HTTP 的通信協議,所以這兩個 option 的第二個參數分別為 false 和 true,完整的代碼及注釋請參考第二章節的命令行開發部分。

    CLI 解析階段

    在解析階段中,通過命令行傳入應用程序的文本來進行處理。處理過程將根據在解析器的實現過程中定義的規則來進行。在 CommandLineParser 類中定義的 parse 方法將用 CLI 定義階段中產生的 Options 實例和一組字符串作為輸入,并返回解析后生成的 CommandLine。

    CLI 解析階段的目標結果就是創建 CommandLine 實例。

    根據上面給出的具體命令行設計,我們可以用如下代碼片段為添加數據源操作解析 Options:


    清單 2. 解析 Options 代碼片段
    CommandLineParser parser = new PosixParser(); CommandLine cmd = parser.parse(options, args); if(cmd.hasOption("h")) { // 這里顯示簡短的幫助信息}

    我們需要判斷命令行中是不是有 h 參數,如果有,就需要應用程序列出簡短的幫助信息,完整的代碼及注釋請參考第二章節的命令行開發部分。

    CLI 詢問階段

    在詢問階段中,應用程序通過查詢 CommandLine,并通過其中的布爾參數和提供給應用程序的參數值來決定需要執行哪些程序分支。這個階段在用戶的代碼中實現,CommandLine 中的訪問方法為用戶代碼提供了 CLI 的詢問能力。

    CLI 詢問階段的目標結果就是將所有通過命令行以及處理參數過程中得到的文本信息傳遞給用戶的代碼。

    根據上面給出的具體命令行設計,我們可以用如下代碼片段為添加數據源操作詢問 Options:


    清單 3. 詢問 Options 代碼片段
    // 獲取 -t 參數值String protocol = cmd.getOptionValue("t"); if(protocol == null) { // 設置默認的 HTTP 傳輸協議} else { // 設置用戶自定義的 HTTP 傳輸協議 }

    如果用戶設置了 t 參數,getOptionValue() 方法將獲取用戶設定的數值,如果沒有指定該參數,getOptionValue() 方法將返回 null,應用程序會根據返回的數值來決定代碼的運行,完整的代碼及注釋請參考第二章節的命令行開發部分。


    基于 Apache Commons CLI 的命令行開發

    Apache Commons CLI 簡介

    Apache Commons CLI 是 Apache 下面的一個解析命令行輸入的工具包,該工具包還提供了自動生成輸出幫助文檔的功能。

    Apache Commons CLI 支持多種輸入參數格式,主要支持的格式有以下幾種:

  • POSIX(Portable Operating System Interface of Unix)中的參數形式,例如 tar -zxvf foo.tar.gz
  • GNU 中的長參數形式,例如 du --human-readable --max-depth=1
  • Java 命令中的參數形式,例如 java -Djava.net.useSystemProxies=true Foo
  • 短杠參數帶參數值的參數形式,例如 gcc -O2 foo.c
  • 長杠參數不帶參數值的形式,例如 ant – projecthelp
  • CLI 命令代碼實現

    命令行程序處理流程相對比較簡單,主要流程為設定命令行參數 -> 解析輸入參數 -> 使用輸入的數據進行邏輯處理。下圖是以 rmdatasource 為例的運行流程圖,圖中加入了實際實現過程中的部分邏輯。


    圖 1. 命令行運行流程圖

    清單 5 是 rmdatasource 的實現代碼片段,主要邏輯在 simpleTest 函數里面。在里面我們首先載入了 ResourceBundle 用于程序的多語言支持,將運行中的輸出信息預先定義在配置文件中(如 xml 或 property 文件),然后用 ResourceBundle 讀取,這樣在運行時可以根據運行環境的 locale 來決定輸出信息語言,也可以讓用戶指定輸出信息的語言。

    然后程序使用 Options 定義命令行的參數,由于參數形式比較簡單,所以使用了 Options 的 addOption 來創建一個參數設定(即 option),如果有復雜參數形式,可以使用 OptionBuilder 來生成 Option,示例如下:


    清單 4. 使用 OptionBuilder 生成 Options 代碼片段
    Option help = new Option("h", "the command help"); Option user = OptionBuilder.withArgName("type").hasArg().withDescription( "target the search type").create("t"); // 此處定義參數類似于 java 命令中的 -D<name>=<value> Option property = OptionBuilder.withArgName("property=value") .hasArgs(2).withValueSeparator().withDescription( "search the objects which have the target property and value").create("D"); Options opts = new Options(); opts.addOption(help); opts.addOption(user); opts.addOption(property);

    在參數設定好后,程序使用 BasicParser 類來解析用戶輸入的參數,當參數中包含 –h 時程序打印命令行的幫助信息(利用 Apache Commons CLI 的 HelpFormatter 自動生成),如果不包含 –h 時,程序將讀取需要的 ip、port 等參數并進行校驗,校驗通過后則調用內部接口進行 rmdatasource 的操作。


    清單 5. rmdatasource 代碼片段
    public class RMDataSource { /** * @param args 輸入參數*/ public static void main(String[] args) { simpleTest(args); } public static void simpleTest(String[] args) { ResourceBundle resourceBundle = ResourceBundle.getBundle("message", Locale.getDefault()); Options opts = new Options(); opts.addOption("h", false, resourceBundle.getString("HELP_DESCRIPTION"));opts.addOption("i", true, resourceBundle.getString("HELP_IPADDRESS")); opts.addOption("p", true, resourceBundle.getString("HELP_PORT")); opts.addOption("t", true, resourceBundle.getString("HELP_PROTOCOL")); BasicParser parser = new BasicParser(); CommandLine cl; try { cl = parser.parse(opts, args); if (cl.getOptions().length > 0) { if (cl.hasOption('h')) { HelpFormatter hf = new HelpFormatter(); hf.printHelp("Options", opts); } else { String ip = cl.getOptionValue("i"); String port = cl.getOptionValue("p"); String protocol = cl.getOptionValue("t"); if(!CIMServiceFactory.getinstance().isIPValid(ip)){ System.err.println(resourceBundle.getString("INVALID_IP"));System.exit(1); } try { int rc = CIMServiceFactory.getinstance().rmdatasource( ip, port, protocol); if (rc == 0) { System.out.println(resourceBundle .getString("RMDATASOURCE_SUCCEEDED")); } else { System.err.println(resourceBundle .getString("RMDATASOURCE_FAILED")); } } catch (Exception e) { System.err.println(resourceBundle .getString("RMDATASOURCE_FAILED")); e.printStackTrace(); } } } else { System.err.println(resourceBundle.getString("ERROR_NOARGS")); } } catch (ParseException e) { e.printStackTrace(); } } }


    基于 Apache Commons CLI 的命令行測試

    CLI 的測試可以分為兩種情況,內部邏輯的測試可以用 JUnit 來實現,方便、簡潔、快速;CLI 的運行可以用腳本(在 Windows 里用 bat 腳本,Linux 上用 shell 腳本)來驗證 CLI 的運行結果。

    JUnit 的運行與測試

    在代碼清單 5 中,我們可以看到 CLI 接收的參數來源于它的一個 String 輸入數組,因此我們可以在 JUnit 的 TestCase 中創建一個 String 數組來模擬輸入,以下清單 6 是對 rmdatsource 的 help 有無參數情況的單元測試的代碼,僅測試了方法的返回值。


    清單 6. JUnit 測試代碼片段
    // 測試帶有 –h 參數的代碼功能public void testHelp() { String args[]={"-h"}; assertEquals(0, RMDataSource.simpleTest(args)); } // 測試沒有帶 –h 參數的代碼功能public void testNoArgs() { String args[] = new String[0]; assertEquals(1, RMDataSource.simpleTest(args)); } // 測試輸入所有正確參數的代碼功能public void testRMDataSource() { /** * 此字符串參數等同于在命令行窗口輸入命令 java rmdatasource -i 192.168.0.2 -p 5988 -t http */ String args[] = new String[]{"-i","192.168.0.2","-p","5988","-t","http"}; assertEquals(0, RMDataSource.simpleTest(args)); }

    CLI 的運行與測試

    開發完成后,將項目編譯成 jar 包即可運行 CLI 了,假定我們的 jar 包名字是 rmdatasource.jar, 則在 jar 包所在目錄運行 java –jar rmdatasource.jar –h 即可得到該 CLI 的幫助信息。同樣,也可以用腳本來運行所開發的命令行工具,對命令的返回值和輸出進行校驗,如下圖清單 7 即為一段 shell 腳本獲取命令的返回值和輸出信息的代碼。


    清單 7. CLI 測試代碼片段
    /opt/ibm/java-i386-60/bin/java -jar /tmp/test/rmdatasource.jar -h > /tmp/test/result echo "cli return code is $?"if [ $? -eq 0 ] then while read line do echo $line done < /tmp/test/result fi


    總結

    隨著科學計算可視化及多媒體技術的飛速發展,人機交互技術不斷更新,但是最傳統的命令行模式依然被廣泛的應用于多個領域,因為命令行界面要較圖形用戶界面節約更多的計算機系統資源。在熟記命令的前提下,使用命令行界面往往要較使用圖形用戶界面的操作速度要快。同時,命令行模式也更加有利于客戶進行二次開發,方便應用程序的整合。Apache Commons CLI 提供了很多實用的工具和類實現,進一步方便了我們對命令行工具的開發,本文介紹了一個完整的實例,希望能對相關讀者在以后的工作有所幫助。


    參考資料

    學習

    • Apache Commons CLI 官方網站:詳細介紹了 Apache Commons CLI 的概念、各階段的定義與實現以及各個實用類的 JavaDoc。

    • Apache Commons CLI 用法簡介:本技術文檔列舉了一些 Apache Commons CLI 中常用的 API,并給出了一些 API 的用例。

    • JUnit Cookbook:本文檔簡略描述了如何使用 JUnit 來編寫測試實例。

    • Java Internationalization: Localization with ResourceBundles:本技術文檔描述了如何使用 ResourceBundle 來實現程序的本土化支持。

    • developerWorks Java 技術專區:這里有數百篇關于 Java 編程各個方面的文章。

    討論

    • 加入 developerWorks 中文社區。查看開發人員推動的博客、論壇、組和維基,并與其他 developerWorks 用戶交流。

    ?

    總結

    以上是生活随笔為你收集整理的使用 Apache Commons CLI 开发命令行工具的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。