> For the complete documentation index, see [llms.txt](https://minguw.gitbook.io/jvm/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://minguw.gitbook.io/jvm/mooc-minilab/command-line-util.md).

# Lab1 CommandLineUtil

## 1. 实验背景

该作业为大作业的预热作业，我们将使用第三方库Commons CLI来编写一个简单的命令行工具。 实验的主要目的是通过这个作业理解什么是命令行工具并熟悉API的使用。

要实现一个命令行工具，需要经历三个过程：定义、解析、使用

* 定义：预定义一组可能的输入选项
* 解析：解析用户传入参数并检验正确性
* 使用：调用解析出的选项的业务逻辑

在命令行模式下运行java，输入java -h(**请先配置好环境变量**)我们可以得到以下的结果。 在安装时因为语言和版本的不同可能结果略有出入，不过这不影响理解。

```
用法: java [-options] class [args...]
           (执行类)
   或  java [-options] -jar jarfile [args...]
           (执行 jar 文件)
其中选项包括:
    -d32          使用 32 位数据模型 (如果可用)
    -d64          使用 64 位数据模型 (如果可用)
    -server       选择 "server" VM
                  默认 VM 是 server.

    -cp <目录和 zip/jar 文件的类搜索路径>
    -classpath <目录和 zip/jar 文件的类搜索路径>
                  用 ; 分隔的目录, JAR 档案
                  和 ZIP 档案列表, 用于搜索类文件。
    -D<名称>=<值>
                  设置系统属性
    -verbose:[class|gc|jni]
                  启用详细输出
    -version      输出产品版本并退出
    -version:<值>
                  警告: 此功能已过时, 将在
                  未来发行版中删除。
                  需要指定的版本才能运行
    ...
    ...
```

一个典型的命令行工具的流程图如下 &#x20;

![](/files/-M7bKapOnMl5WCHeaVt2)

## 2. 实验要求

### 2.1 实验输入

程序的输入是一个字符串，对于一个合法输入有以下的要求

* 如果一个选项带有必选参数，则参数必须存在且紧跟在选项，两者之间可以包括多个空格作为间隔
* 不要求 各选项和其可能带有的参数  与  用户参数 的顺序关系
* 输入不包含-h选项时，必须带有至少一个用户参数

**用户参数定义：**

> **除了预定义选项和预定义选项的参数以外的内容。举例来说，在2.3中我们定义了三个参数，其中只有-p需要一个参数，其余选项都不带参数。那么如果输入为 -h -p arg0，这里的arg0就会被当成-p的参数，而如果输入为 -h -p hello arg0，那么hello为-p的选项参数而arg0就是用户参数**

### 2.2 实验输出

程序的合法输出包括

* 在输入合法时，使用标准输出方法将业务逻辑的结果打印到控制台(如果有)
* 在输入不合法时抛出相应异常

### 2.3 实验要求

在本次实验中需要完成以下参数的实现 格式说明： -开头为选项的简写，--开头为选项的全名，跟在后面的符号是选项的参数

| 参数              | 主要功能                                |
| --------------- | ----------------------------------- |
| -h --help       | 打印出所有预定义的选项与用法                      |
| -p --print ：arg | 打印出arg                              |
| -s              | 将CommandlineUtil中sideEffect变量置为true |

其他要求： 1. 选项缺少参数时应该在标准输出中打印ParseException的错误信息并使用System.exit(-1)退出程序 1. 无论处于整条指令的什么位置，只要使用了-h指令，其余指令失效。但其余参数仍需要是合法形式，否则采用第一条规则 1. 当不包含-h选项时，如果用户参数为空，则输出自定义错误提示

### 2.4 代码指导

**在开始阅读这段指导之前，我们强烈建议直接阅读**[**官方文档**](https://commons.apache.org/proper/commons-cli/usage.html)**来获取你所需要的一切。这其中就有一个非常完整的实现示例。不要害怕，阅读完全文也就5-10分钟，之后你就可以用几十行代码实现我们的作业了\~**

**在之后的大作业中我们不会提供详细到API级别的文档。因此，掌握阅读官方文档的能力十分重要。**

在CommandlineUtil中我们定义了三个静态变量

```java
    private static CommandLine commandLine;
    private static CommandLineParser parser = new DefaultParser();
    private static Options options = new Options();
```

其中，options是用来添加预定义的选项规则的，parser负责解析输入并把结果传给commandLine

Step1 创建Option [API](https://commons.apache.org/proper/commons-cli/javadocs/api-release/index.html)

```java
采用以下方法之一完成option构造，调用形式为options.add(new Option(...))

方法1：
Option(String opt, boolean hasArg, String description)
Option(String opt, String description)
Option(String opt, String longOpt, boolean hasArg, String description)

方法2：
Option someOption = OptionBuilder.withArgName( "name" )
                                .hasArg()
                                .withDescription(  "description" )
                                .create( "someOption" );
```

Step2 解析输入 [API](https://commons.apache.org/proper/commons-cli/javadocs/api-release/index.html)

```java
parser.parse(options,args) //args即main函数的参数
```

Step3 处理选项 [API](https://commons.apache.org/proper/commons-cli/javadocs/api-release/index.html)

```java
首先获取参数
if( line.hasOption( "someOption" ) ) {
    // 如果存在可能的参数可以这样尝试获取
    this.someField = commandLine.getOptionValue( "someOption" );
}

也可以通过commandLine.getArgs()获取全部参数

获取完参数之后就可以调用自己的业务逻辑来实现要求了
```

格式化输出 [API](https://commons.apache.org/proper/commons-cli/javadocs/api-release/index.html)

```java
 String header = "header of help message";
 String footer = "footer of help message";

 HelpFormatter formatter = new HelpFormatter();
 formatter.printHelp("myapp", header, options, footer);
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://minguw.gitbook.io/jvm/mooc-minilab/command-line-util.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
