新聞中心
CLI
CLI,全稱為命令行界面(Command Line Interface),是一種用于通過鍵盤輸入指令與操作系統(tǒng)進(jìn)行交互的軟件機(jī)制。這種界面是在圖形用戶界面得到普及之前使用最為廣泛的用戶界面,并且, 即使在當(dāng)前圖形用戶界面廣泛使用的環(huán)境下,CLI仍然有其獨特的優(yōu)勢和廣泛的應(yīng)用。

創(chuàng)新互聯(lián)建站公司2013年成立,先為??档确?wù)建站,??档鹊仄髽I(yè),進(jìn)行企業(yè)商務(wù)咨詢服務(wù)。為??灯髽I(yè)網(wǎng)站制作PC+手機(jī)+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問題。
對于CLI,它的一個重要特性就是效率。用戶可以在一條文本命令中對多個文件執(zhí)行操作,而不需要在各個窗口之間切換,節(jié)省了大量時間。此外,如果你已經(jīng)熟悉了這些命令,那么你可以非??焖俚貫g覽系統(tǒng)并與之交互。
構(gòu)建CLI的工具很多,今天主要基于Java語言來實現(xiàn),其中Apache Commons CLI框架提供了這樣的便利。今天結(jié)合之前學(xué)習(xí)的graalVM提供的native-image工具,來生成一個exe類型的可執(zhí)行文件,由于graalVM的跨平臺性,我們還能生成各個平臺的CLI命令來輔助完成更多的工作。
Apache Commons CLI是一個用于編寫命令行界面的Java庫。它提供了一個靈活的框架,可以很容易地定義和解析命令行參數(shù)。這個庫的主要優(yōu)點是它可以處理各種類型的參數(shù),包括選項、位置參數(shù)、可選參數(shù)等。
構(gòu)成
下面以native-image為例,通過在終端輸入native-image --help可以看到以下信息
_> native-image --help
GraalVM Native Image (https://www.graalvm.org/native-image/)
This tool can ahead-of-time compile Java code to native executables.
Usage: native-image [options] class [imagename] [options]
(to build an image for a class)
or native-image [options] -jar jarfile [imagename] [options]
(to build an image for a jar file)
or native-image [options] -m [/] [options]
native-image [options] --module [/] [options]
(to build an image for a module)
where options include:
@argument files one or more argument files containing options
-cp
-classpath
--class-path
A ; separated list of directories, JAR archives,
and ZIP archives to search for class files.
-p
--module-path ...
A ; separated list of directories, each directory
is a directory of modules. 一個合格的CLI基本都會提供help選項來展示,這個CLI的語法、選項以及功能描述。從上面的輸出可以看到help主要包括:
- 介紹:主要對命令的功能的描述,包括官網(wǎng)、版本以及一些內(nèi)在系數(shù)等
- 用法:包括命令語法格式、配置項、參數(shù)等信息
- 參數(shù)說明:具體配置項參數(shù)的說明,以及具體的功能描述
Common-CLI
- 定義階段:在Java代碼中定義Option參數(shù),定義參數(shù)、是否需要輸入值、簡單的描述等
- 解析階段:應(yīng)用程序傳入?yún)?shù)后,CLI進(jìn)行解析
- 詢問階段:通過查詢CommandLine詢問進(jìn)入到哪個程序分支中
定義階段
主要是借助Option類提供的API來構(gòu)建各種選項以及參數(shù)信息,下面是對應(yīng)API的描述:
|
返回值 |
方法名 |
說明 |
|
Options |
addOption(Option opt) |
添加一個選項實例 |
|
Options |
addOption(String opt, boolean hasArg, String description) |
添加一個只包含短名稱的選項 |
|
Options |
addOption(String opt, String description) |
添加一個只包含短名稱的選項 |
|
Options |
addOption(String opt, String longOpt, boolean hasArg, String description) |
添加一個包含短名稱和長名稱的選項 |
|
Options |
addOptionGroup(OptionGroup group) |
添加一個選項組 |
|
List |
getMatchingOptions(String opt) |
獲得匹配選項的長名稱集合 |
|
Option |
getOption(String opt) |
通過長名稱或短名稱獲得選項 |
|
OptionGroup |
getOptionGroup(Option opt) |
獲得選項所在的選項組 |
|
Collection |
getOptions() |
獲得一個只讀的選項集合 |
|
List |
getRequiredOptions() |
獲得必須的選項集合 |
|
boolean |
hasLongOption(String opt) |
判斷是否存在選項 |
|
boolean |
hasOption(String opt) |
判斷是否存在選項 |
|
boolean |
hasShortOption(String opt) |
判斷是否存在選項 |
解析階段
主要對輸入?yún)?shù)的解析,也就是main方法的參數(shù),默認(rèn)提供下面3中語法解析的支持:
- DefaultParser:提供了基礎(chǔ)的解析功能,能解析簡單的命令行參數(shù)。(比如:java -Djava.awt.headless=true -Djava.net.useSystemProxies=true Foo)
- PosixParser:提供了解析POSIX形式參數(shù)的功能。(比如:tar -zxvf foo.tar.gz)
- GnuParser:提供了解析長參數(shù)及Java命令中參數(shù)的功能。(比如:du --human-readable --max-depth=1)
詢問階段
基于上一步解析后,會將參數(shù)解析成CommandLine,結(jié)合Option中的配置,需要我們完成各種配置、參數(shù)匹配后的業(yè)務(wù)處理流程,類型下面這樣:
if( commandLine.hasOption("help") ){
helper.printHelp("calendar [options] \n\nwhere options include:", null, options, null, false);
return;
}
if( commandLine.hasOption("version") ){
printResult("1.0.0");
return;
}解析的過程有時候會比較些復(fù)雜,示例中是針對單一選項的分支,當(dāng)多個選項混合使用時,比如tar -zxvf xxx.tar.gz這樣的,當(dāng)然前提是我們定義的CLI支持這種風(fēng)格。
示例
下面通過一個簡單的示例看下如何構(gòu)建一個CLI的工具:該示例的作用是按指定格式輸出當(dāng)前日期:
clendar -o yyyy-MM-dd
- 定義配置項
private static Options initOptions() {
Options options = new Options();
options.addOption(Option.builder("H")
.longOpt("help")
.desc("show help information").build());
options.addOption(Option.builder("V")
.longOpt("version")
.desc("show help information").build());
options.addOption(Option.builder("O")
.longOpt("out")
.hasArg(true)
.argName("fmt") // 只是定義
.required(false)
.desc("configure the date output format").build());
return options;
}
- 解析參數(shù)
private static CommandLine parseArguments(Options options, String[] args){
CommandLineParser parser = new DefaultParser();
try {
return parser.parse(options, args);
} catch (ParseException e) {
System.err.println(e.getMessage());
}
return null;
}
- 詢問階段
private static void handleCommand(Options options, CommandLine commandLine) {
if(ArrayUtils.isEmpty(commandLine.getOptions()) ){
printResult("Please specify options for calendar building or use --help for more info.");
return;
}
if( commandLine.hasOption("help") ){
helper.printHelp("calendar [options] \n\nwhere options include:", null, options, null, false);
return;
}
if( commandLine.hasOption("version") ){
printResult("1.0.0");
return;
}
if( commandLine.hasOption("out") ){
String fmt = commandLine.getOptionValue("out");
if(StringUtils.isEmpty(fmt)){
fmt = "yyyy-MM-dd HH:mm:ss";
}
printResult(DateFormatUtils.format(new Date(), fmt));
return;
}
// calendar: 'x' is not a git command. See 'calendar --help'.
helper.printHelp(String.format("calendar: '%s' is not a calendar command. See 'calendar --help'.", Arrays.toString(commandLine.getArgs())), options, false);
}定義程序入口:
public static void main(String[] args) {
// 定義階段
Options options = initOptions();
// 解析階段
CommandLine commandLine = parseArguments(options, args);
// 詢問階段
handleCommand(options, commandLine);
}
打包
這里我們引入maven-assembly-plugin插件,主要幫助在打包時將依賴包一并寫入jar文件,同時將入口文件定義到manifest:
org.apache.maven.plugins
maven-assembly-plugin
3.3.0
package-jar-with-dependencies
package
single
${main-class}
jar-with-dependencies
可以直接通過maven插件或者下的命令,將上面的代碼打包成jar文件
mvn clean package
測試jar
如果安裝上面的配置,最終會在項目target目錄輸出一個以jar-with-dependencies為后綴的jar文件,通過下面的命令可以測試cli命令
java -jar ./target/calendar-jar-with-dependencies.jar -h這樣的CLI可不是我們想要的,一來需要依賴JRE的運(yùn)行環(huán)境,同時調(diào)用極其不方便。
生成exe
如果你看過之前的文章,關(guān)于GraalVM的使用,按照文檔下載并配置好運(yùn)行環(huán)境后,可以通過下面的命令對上一步的jar文件進(jìn)一步處理
native-image -jar [jar] -o [name]
native-image -jar ./target/calendar-jar-with-dependencies.jar -o calendar通過上面的命令會生成一個calendar.exe文件,這樣將其加入到環(huán)境變量后,則可以在windows平臺終端上使用了
對于不喜歡直接使用命令的,當(dāng)然這里也可以使用插件exec-maven-plugin,在maven生命周期package階段,自動執(zhí)行上面的命令,這樣整個過程只需要執(zhí)行mvn clean package即可
org.codehaus.mojo
exec-maven-plugin
3.1.0
native-image-app
package
exec
native-image
-jar
${project.basedir}/target/${project.build.finalName}-jar-with-dependencies.jar
-o
${project.build.finalName}
測試exe
在終端執(zhí)行下面的命令接口看到預(yù)期的結(jié)果:
calendar.exe -O yyyy-MM-dd
總結(jié)
總的來說,Apache Commons CLI是一個非常強(qiáng)大的工具,可以幫助你輕松地處理命令行參數(shù)。無論你的應(yīng)用程序需要處理多少個參數(shù),或者這些參數(shù)的類型是什么, Commons CLI都可以提供幫助。
網(wǎng)站名稱:怎么基于Java編寫一個CLI工具?
文章位置:http://www.dlmjj.cn/article/copceeg.html


咨詢
建站咨詢
