执行non-Java processes命令行的工具ExecHelper

在Java程序里执行操作命令行工具类:

    public static void main(String[] args) {

        try {
            /*String file = ExecHelper.exec(
                new String[]{"XXXX"}, "GBK"
            ).getOutput();

            String hello = ExecHelper.execUsingShell(
                "echo ‘Hello World‘"
            ).getOutput();*/

            ExecHelper helper = ExecHelper.execUsingShell("java -version", "GBK");
            System.out.println(helper.getResult());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

输出结果:

java version "1.6.0_37"
Java(TM) SE Runtime Environment (build 1.6.0_37-b06)
Java HotSpot(TM) Client VM (build 20.12-b01, mixed mode, sharing)

ExecHelper代码实现:

package com.yzu.zhang.utils;

import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;

/**
 * Convenience methods for executing non-Java processes.
 * @since ostermillerutils 1.06.00
 */
public final class ExecHelper {

    /**
     * Executes the specified command and arguments in a separate process, and waits for the
     * process to finish.
     * @since ostermillerutils 1.06.00
     */
    public static ExecHelper exec(String[] cmdarray) throws IOException {
        return new ExecHelper(Runtime.getRuntime().exec(cmdarray), null);
    }

    /**
     * Executes the specified command and arguments in a separate process, and waits for the
     * process to finish.
     * @since ostermillerutils 1.06.00
     */
    public static ExecHelper exec(String[] cmdarray, String[] envp) throws IOException {
        return new ExecHelper(Runtime.getRuntime().exec(cmdarray, envp), null);
    }

    /**
     * Executes the specified command and arguments in a separate process, and waits for the
     * process to finish.
     * @since ostermillerutils 1.06.00
     */
    public static ExecHelper exec(String[] cmdarray, String[] envp, File dir) throws IOException {
        return new ExecHelper(Runtime.getRuntime().exec(cmdarray, envp), null);
    }

    /**
     * Executes the specified command and arguments in a separate process, and waits for the
     * process to finish.
     * @since ostermillerutils 1.06.00
     */
    public static ExecHelper exec(String[] cmdarray, String charset) throws IOException {
        return new ExecHelper(Runtime.getRuntime().exec(cmdarray), charset);
    }

    /**
     * Executes the specified command and arguments in a separate process, and waits for the
     * process to finish.
     * @since ostermillerutils 1.06.00
     */
    public static ExecHelper exec(String[] cmdarray, String[] envp, String charset) throws IOException {
        return new ExecHelper(Runtime.getRuntime().exec(cmdarray, envp), charset);
    }

    /**
     * Executes the specified command and arguments in a separate process, and waits for the
     * process to finish.
     * @since ostermillerutils 1.06.00
     */
    public static ExecHelper exec(String[] cmdarray, String[] envp, File dir, String charset) throws IOException {
        return new ExecHelper(Runtime.getRuntime().exec(cmdarray, envp), charset);
    }

    /**
     * Executes the specified command using a shell.  On windows uses cmd.exe or command.exe.
     * On other platforms it uses /bin/sh.
     * @since ostermillerutils 1.06.00
     */
    public static ExecHelper execUsingShell(String command) throws IOException {
        return execUsingShell(command, null);
    }

    /**
     * Executes the specified command using a shell.  On windows uses cmd.exe or command.exe.
     * On other platforms it uses /bin/sh.
     * @since ostermillerutils 1.06.00
     */
    public static ExecHelper execUsingShell(String command, String charset) throws IOException {
        if (command == null) throw new NullPointerException();
        String[] cmdarray;
        String os = System.getProperty("os.name");
        if (os.equals("Windows 95") || os.equals("Windows 98") || os.equals("Windows ME")){
            cmdarray = new String[]{"command.exe", "/C", command};
        } else if (os.startsWith("Windows")){
            cmdarray = new String[]{"cmd.exe", "/C", command};
        } else {
            cmdarray = new String[]{"/bin/sh", "-c", command};
        }
        return new ExecHelper(Runtime.getRuntime().exec(cmdarray), charset);
    }

    /**
     * Take a process, record its standard error and standard out streams, wait for it to finish
     *
     * @param process process to watch
     * @throws SecurityException if a security manager exists and its checkExec method doesn‘t allow creation of a subprocess.
     * @throws IOException - if an I/O error occurs
     * @throws NullPointerException - if cmdarray is null
     * @throws IndexOutOfBoundsException - if cmdarray is an empty array (has length 0).
     *
     * @since ostermillerutils 1.06.00
     */
    private ExecHelper(Process process, String charset) throws IOException {
        StringBuffer output = new StringBuffer();
        StringBuffer error = new StringBuffer();

        Reader stdout;
        Reader stderr;

        if (charset == null){
            // This is one time that the system charset is appropriate,
            // don‘t specify a character set.
            stdout = new InputStreamReader(process.getInputStream());
            stderr = new InputStreamReader(process.getErrorStream());
        } else {
            stdout = new InputStreamReader(process.getInputStream(), charset);
            stderr = new InputStreamReader(process.getErrorStream(), charset);
        }
        char[] buffer = new char[1024];

        boolean done = false;
        boolean stdoutclosed = false;
        boolean stderrclosed = false;
        while (!done){
            boolean readSomething = false;
            // read from the process‘s standard output
            if (!stdoutclosed && stdout.ready()){
                readSomething = true;
                int read = stdout.read(buffer, 0, buffer.length);
                if (read < 0){
                    readSomething = true;
                    stdoutclosed = true;
                } else if (read > 0){
                    readSomething = true;
                    output.append(buffer, 0, read);
                }
            }
            // read from the process‘s standard error
            if (!stderrclosed && stderr.ready()){
                int read = stderr.read(buffer, 0, buffer.length);
                if (read < 0){
                    readSomething = true;
                    stderrclosed = true;
                } else if (read > 0){
                    readSomething = true;
                    error.append(buffer, 0, read);
                }
            }
            // Check the exit status only we haven‘t read anything,
            // if something has been read, the process is obviously not dead yet.
            if (!readSomething){
                try {
                    this.status = process.exitValue();
                    done = true;
                } catch (IllegalThreadStateException itx){
                    // Exit status not ready yet.
                    // Give the process a little breathing room.
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException ix){
                        process.destroy();
                        throw new IOException("Interrupted - processes killed");
                    }
                }
            }
        }

        this.output = output.toString();
        this.error = error.toString();
    }

    /**
     * The output of the job that ran.
     *
     * @since ostermillerutils 1.06.00
     */
    private String output;

    /**
     * Get the output of the job that ran.
     *
     * @return Everything the executed process wrote to its standard output as a String.
     *
     * @since ostermillerutils 1.06.00
     */
    public String getOutput(){
        return output;
    }

    /**
     * The error output of the job that ran.
     *
     * @since ostermillerutils 1.06.00
     */
    private String error;

    /**
     * Get the error output of the job that ran.
     *
     * @return Everything the executed process wrote to its standard error as a String.
     *
     * @since ostermillerutils 1.06.00
     */
    public String getError(){
        return error;
    }

    /**
     * The status of the job that ran.
     *
     * @since ostermillerutils 1.06.00
     */
    private int status;

    /**
     * Get the status of the job that ran.
     *
     * @return exit status of the executed process, by convention, the value 0 indicates normal termination.
     *
     * @since ostermillerutils 1.06.00
     */
    public int getStatus(){
        return status;
    }

    public String getResult(){
        if(!StringUtils.isBlank(output, error)){
            return output + "\n\n" +error;
        }
        if(StringUtils.isNotBlank(output)){
            return output;
        }
        if(StringUtils.isNotBlank(error)){
            return error;
        }
        return null;
    }
}
时间: 2024-08-09 18:50:09

执行non-Java processes命令行的工具ExecHelper的相关文章

libvirt 命令行交互工具之virsh

libvirt是当前主流VM最低层库.IBM PowerVM也不例外,libvirt是深入玩虚拟化必须玩转的东西; 简单测试玩玩libvirt 的virsh命令行交互工具, 你我都知识libvirt大体上主要有3个组件,分别是: 1. libvirt daemon进程 2. 命令行工具virsh 3. libvirt API virsh命令使用 virsh <command> <domain-id> [OPTIONS] virsh既有命令行模式,也有交互模式,在命令行直接输入vir

【解锁】Linenoise——C命令行处理工具

Linenoise 今天解锁一个开源的REPL工具--Linenoise.Linenoise是可以完全代替readline的,非常轻量级的命令行处理工具.Redis,MongoDB和Android都将Linenoise作为命令行解析工具,那么今天我们就来解锁这个开源的命令行处理工具,也许某一天在你的项目里会派上用场. 特性 支持单行和多行编辑模式,实现了常用的键绑定. 支持历史命令记录 支持命令不全 支持命令提示 超轻量级,大约1100行代码(readline大约30,000行代码) 非常方便的

Linux上超酷的命令行扩展工具Oh My Zsh

Oh My Zsh 是一款社区驱动的命令行工具,正如它的主页上说的,Oh My Zsh 是一种生活方式.它基于 zsh 命令行,提供了主题配置,插件机制,已经内置的便捷操作.给我们一种全新的方式使用命令行. 什么是 Oh My ZshOh My Zsh 这个名字听起来就很有意思~, 它是基于 zsh 命令行的一个扩展工具集,提供了丰富的扩展功能. Oh My Zsh 的主页上,对它的定义有了明确的解释:http://ohmyz.sh 关于 zsh,它是一种命令行程序.我们 MAC 系统上默认使用

PowerCmd(命令行增强工具) 2.2 免费版

软件名称: PowerCmd(命令行增强工具) 2.2 免费版 软件语言: 英文 授权方式: 免费软件 运行环境: Win7 / Vista / Win2003 / WinXP 软件大小: 1.8MB 图片预览: 软件简介: 一款Windows CMD软件的增强工具,可以比普通CMD工具提供更多选项 软件下载页面:http://www.bkill.com/download/9020.html 软件下载地址:电信下载 联通下载

12款最佳Linux命令行终端工具

12款最佳Linux命令行终端工具 如果你跟我一样,整天要花大量的时间使用Linux命令行,而且正在寻找一些可替代系统自带的老旧且乏味的终端软件,那你真是找对了文章.我这里搜集了一些非常有趣的终端软件,可以用来替代debian系的Linux原生终端. Tilda tilda 这是一款可配置的雷神之锤风格的终端工具,也就是说,当用户敲击配置好的热键(缺省是F1)时,这个终端会从屏幕的顶端滑出,就跟雷神之锤游戏中的效果一样. 它的安装方法: apt-get install tilda Tilda跟其

[转]12款最佳Linux命令行终端工具

摘要 “工欲善其事必先利其器”,作为菜鸟,也是从别人那里偷学来的一些东东.今天看到同事用到一个终端命令行工具,觉得自己弱爆了.然后在网上搜了下该工具.发现类似的工具还是挺多的,只是自己不知道罢了. 原文链接:12款最佳Linux命令行终端工具 内容 如果你跟我一样,整天要花大量的时间使用 Linux 命令行,而且正在寻找一些可替代系统自带的老旧且乏味的终端软件,那你真是找对了文章.我这里搜集了一些非常有趣的终端软件,可以用来替代 debian 系的 Linux 原生终端. Tilda 这是一款可

iOS系统提供开发环境下命令行编译工具:xcodebuild

iOS系统提供开发环境下命令行编译工具:xcodebuild[3] xcodebuild 在介绍xcodebuild之前,需要先弄清楚一些在XCode环境下的一些概念[4]: Workspace:简单来说,Workspace就是一个容器,在该容器中可以存放多个你创建的Xcode Project, 以及其他的项目中需要使用到的文件. 使用Workspace的好处有: 1),扩展项目的可视域,即可以在多个项目之间跳转,重构,一个项目可以使用另一个项目的输出.Workspace会负责各个Project

命令行开发工具

android 1.全局选项: -s    --silent : Silent mode,show errors only -v    --verbose : Verbose mode,show errors,warnings and all messages         --clear-cache:Clear the SDK Manager repository manifest cache -h   --help : Help on a specific command 2.子命令: s

python之命令行解析工具argparse

以前写python的时候都会自己在文件开头写一个usgae函数,用来加上各种注释,给用这个脚本的人提供帮助文档. 今天才知道原来python已经有一个自带的命令行解析工具argparse,用了一下,效果还不错. argparse的官方文档请看 https://docs.python.org/2/howto/argparse.html#id1 from argparse import ArgumentParser p = ArgumentParser(usage='it is usage tip'