Commons CLI 示例

概述

 在定时任务中,经常需要通过shell脚本调起各种任务,如图所示:


具体的任务实现需要定义一套CLI(命令行接口)。所谓的CLI,就是编写一套命令行接口,然后通过解析命令行,将参数传递给我们的程序去执行相应的任务。最常见的就是我们的java命令,例如:


这个java -version就是一个命令行,其中-vresion就是选项。

CLI共分为三个阶段,1-定义阶段,2-解析阶段,3-询问阶段,其中定义阶段对接口进行的定义,包括选项,参数。执行的时候就走2、3阶段。我们先来看看每个阶段都可以做什么。

定义阶段

 /**
         * 1、定义阶段,在此阶段定义命令行的选项
         * */

        //Options是Option的容器
        Options options = new Options();

        //添加一个Option,t-表示选项名称,false-表示是否含有参数,第三个参数-选项说明
        //布尔类型选项
        options.addOption("t", false, "display current time");
        //带参选项(只能带一个参数,多个参数请自行用分割符分割)
        options.addOption("add",true,"add operation");

Option还可以通过OptionBuilder(1.3以后变成了Option.Builder)进行语义化的定义:

//withArgName:参数名称,create:选项名称
        Option ping   = OptionBuilder.withArgName("ip").hasArg().
                withDescription("ping the given ip").create( "ping" );

        //带属性
        Option property  = OptionBuilder.withArgName( "property=value" )
                .hasArgs()//有多个参数
                .withValueSeparator()//分隔符,默认=号
                .withDescription( "use value for given property" )
                .create( "D" );


解析阶段

/**
         * 2、解析阶段:解析命令,分离出选项和参数
         * */
        CommandLineParser parser = new DefaultParser();

        CommandLine cmd = null;
        try{
            cmd = parser.parse(options, args);//解析参数
        }catch(ParseException e){
           System.out.println("解析命令异常"+e.getMessage());
        }

询问阶段

/**
         * 3、询问阶段,根据选项及参数进行相应操作
         * */
        if(cmd != null){
            if(cmd.hasOption("t")) {//检查是否含有选项
                Date now = new Date();
                System.out.println("the time is "+now.toString());
            }else if(cmd.hasOption("add")){
                String arg = cmd.getOptionValue("add");//获取参数
                String[] nums = arg.split("#");
                int res = Integer.parseInt(nums[0])+Integer.parseInt(nums[1]);
                System.out.println("结果:"+res);
            }
        }

至此,一个完整的CLI就开发完成了。在IDEA中,可以通过debug来测试:


在Program arguments中设置选项,例如-t。然后运行,结果如下:


那么如何通过shell或者cmd运行呢?

我们可以将程序打包成jar,然后通过java命令去执行。首先在pom文件里面添加打包插件:

<build>
        <plugins>
            <!--打包成可执行jar-->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>2.3</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <transformers>
                                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                    <mainClass>com.xxx.demo.CliComplexDemo</mainClass>
                                </transformer>
                            </transformers>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

记得指定主类,我们这里是com.xxx.demo.CliComplexDemo,然后运行maven package,在target目录里面会有jar生成。然后运行命令

java -jar commonexec-1.0-SNAPSHOT.jar -version

运行结果如下:



如果打印help信息?

commons-cli提供了HelpFormatter,可以很方便的生成usage help信息:

 if(line.hasOption("help")){
                HelpFormatter formatter = new HelpFormatter();
                formatter.printHelp( "run", options );
            }

如何在java中调用CLI?
String command = "java -jar commonexec-1.0-SNAPSHOT.jar " + args;//需要执行的命令
        CommandLine commandLine = CommandLine.parse(command);

        //申明一个命令执行器
        DefaultExecutor executor = new DefaultExecutor();

        //设置输出日志
        String logFile = "d:\\logFile.log";
        File logFilePath = new File(logFile);
        FileOutputStream fos = new FileOutputStream(logFilePath);
        PumpStreamHandler pumpStreamHandler = new PumpStreamHandler(fos);
        executor.setStreamHandler(pumpStreamHandler);


        //executor.setExitValue(0);//设置为0
        int exitValue = executor.execute(commandLine);//执行命令
        System.out.println("命令返回:"+exitValue);

其中command就是我们之前跑的命令,只是这里变成了从java中调用。

demo地址:http://download.csdn.net/download/gameloft9/10246176


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值