java runtime.getruntime()从执行命令行程序获取输出

时间:2011-04-19 02:51:29

标签: java runtime

我正在使用运行时从我的Java程序运行命令提示符命令。但是我不知道如何获得命令返回的输出。

这是我的代码:

Runtime rt = Runtime.getRuntime();

String[] commands = {"system.exe" , "-send" , argument};

Process proc = rt.exec(commands);

我尝试过System.out.print(proc);,但没有返回任何内容。该命令的执行应返回由分号分隔的两个数字,我怎么能在变量中得到这个以打印出来?

以下是我现在使用的代码:

String[] commands = {"system.exe","-get t"};

Process proc = rt.exec(commands);

InputStream stdin = proc.getInputStream();
InputStreamReader isr = new InputStreamReader(stdin);
BufferedReader br = new BufferedReader(isr);

String line = null;
System.out.println("<OUTPUT>");

while ( (line = br.readLine()) != null)
     System.out.println(line);

System.out.println("</OUTPUT>");
int exitVal = proc.waitFor();
System.out.println("Process exitValue: " + exitVal);

但是我没有得到任何东西作为我的输出,但当我自己运行该命令它工作正常。

13 个答案:

答案 0 :(得分:197)

这是要走的路:

Runtime rt = Runtime.getRuntime();
String[] commands = {"system.exe","-get t"};
Process proc = rt.exec(commands);

BufferedReader stdInput = new BufferedReader(new 
     InputStreamReader(proc.getInputStream()));

BufferedReader stdError = new BufferedReader(new 
     InputStreamReader(proc.getErrorStream()));

// read the output from the command
System.out.println("Here is the standard output of the command:\n");
String s = null;
while ((s = stdInput.readLine()) != null) {
    System.out.println(s);
}

// read any errors from the attempted command
System.out.println("Here is the standard error of the command (if any):\n");
while ((s = stdError.readLine()) != null) {
    System.out.println(s);
}

更好地阅读Javadoc以获取更多详细信息hereProcessBuilder是使用

的不错选择

答案 1 :(得分:54)

更快的方法是:

public static String execCmd(String cmd) throws java.io.IOException {
    java.util.Scanner s = new java.util.Scanner(Runtime.getRuntime().exec(cmd).getInputStream()).useDelimiter("\\A");
    return s.hasNext() ? s.next() : "";
}

这基本上是这个的浓缩版本:

public static String execCmd(String cmd) throws java.io.IOException {
    Process proc = Runtime.getRuntime().exec(cmd);
    java.io.InputStream is = proc.getInputStream();
    java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
    String val = "";
    if (s.hasNext()) {
        val = s.next();
    }
    else {
        val = "";
    }
    return val;
}

我知道这个问题已经过时但是我发布了这个答案,因为我觉得这可能会更快。

答案 2 :(得分:11)

除了按照建议的Senthil使用ProcessBuilder之外,请务必阅读并实施When Runtime.exec() won't所有建议。

答案 3 :(得分:8)

@Senthil和@Arend回答(https://stackoverflow.com/a/5711150/2268559)提到了ProcessBuilder。以下是使用ProcessBuilder为命令指定环境变量和工作文件夹的示例:

    ProcessBuilder pb = new ProcessBuilder("ls", "-a", "-l");

    Map<String, String> env = pb.environment();
    // If you want clean environment, call env.clear() first
    // env.clear()
    env.put("VAR1", "myValue");
    env.remove("OTHERVAR");
    env.put("VAR2", env.get("VAR1") + "suffix");

    File workingFolder = new File("/home/user");
    pb.directory(workingFolder);

    Process proc = pb.start();

    BufferedReader stdInput = new BufferedReader(new InputStreamReader(proc.getInputStream()));

    BufferedReader stdError = new BufferedReader(new InputStreamReader(proc.getErrorStream()));

    // read the output from the command
    System.out.println("Here is the standard output of the command:\n");
    String s = null;
    while ((s = stdInput.readLine()) != null)
    {
        System.out.println(s);
    }

    // read any errors from the attempted command
    System.out.println("Here is the standard error of the command (if any):\n");
    while ((s = stdError.readLine()) != null)
    {
        System.out.println(s);
    }

答案 4 :(得分:5)

我们也可以使用流来获取命令输出:

public static void main(String[] args) throws IOException {

        Runtime runtime = Runtime.getRuntime();
        String[] commands  = {"free", "-h"};
        Process process = runtime.exec(commands);

        BufferedReader lineReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
        lineReader.lines().forEach(System.out::println);

        BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
        errorReader.lines().forEach(System.out::println);
    }

答案 5 :(得分:4)

如果使用的类路径上已经有Apache commons-io,则可以使用:

Process p = new ProcessBuilder("cat", "/etc/something").start();
String stderr = IOUtils.toString(p.getErrorStream(), Charset.defaultCharset());
String stdout = IOUtils.toString(p.getInputStream(), Charset.defaultCharset());

答案 6 :(得分:4)

在撰写本文时,所有其他包含代码的答案都可能导致死锁。

进程对stdoutstderr输出具有有限的缓冲区。如果您不同时收听它们,那么当您尝试阅读另一种时,它们中的一种会变满。例如,您可能正在等待读取stdout,而进程正在等待写入stderr。您无法从stdout缓冲区读取数据,因为该缓冲区为空,并且该进程无法写入stderr缓冲区,因为该缓冲区已满。你们彼此永远在等待。

这是一种读取进程输出而又不存在死锁风险的方法:

public final class Processes
{
    private static final String NEWLINE = System.getProperty("line.separator");

    /**
     * @param command the command to run
     * @return the output of the command
     * @throws IOException if an I/O error occurs
     */
    public static String run(String... command) throws IOException
    {
        ProcessBuilder pb = new ProcessBuilder(command).redirectErrorStream(true);
        Process process = pb.start();
        StringBuilder result = new StringBuilder(80);
        try (BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream())))
        {
            while (true)
            {
                String line = in.readLine();
                if (line == null)
                    break;
                result.append(line).append(NEWLINE);
            }
        }
        return result.toString();
    }

    /**
     * Prevent construction.
     */
    private Processes()
    {
    }
}

关键是使用ProcessBuilder.redirectErrorStream(true),它将把stderr重定向到stdout流中。这使您可以读取单个流,而不必在stdoutstderr之间切换。如果要手动执行此操作,则必须consume the streams in two different threads以确保您永远不会阻止。

答案 7 :(得分:1)

创建类:

public class Utils {
public static final String SHEL_EXECUTE_ERROR = "SHEL_EXECUTE_ERROR";
public static String shellExec(String cmdCommand) {
    final StringBuilder stringBuilder = new StringBuilder();
    try {
        final Process process = Runtime.getRuntime().exec(cmdCommand);
        final BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
        String line;
        while ((line = bufferedReader.readLine()) != null) {
            stringBuilder.append(line);
        }

    } catch (Exception e) {
        return SHEL_EXECUTE_ERROR;
    }
    return stringBuilder.toString();
}

}

并使用:

final String shellExec = shellExec("cmd /c ver");
final String versionOS = shellExec.equals(SHEL_EXECUTE_ERROR) ? "empty" : shellExec;

答案 8 :(得分:0)

改编自之前的回答

public static String execCmdSync(String cmd, CmdExecResult callback) throws java.io.IOException, InterruptedException {
    RLog.i(TAG, "Running command:", cmd);

    Runtime rt = Runtime.getRuntime();
    Process proc = rt.exec(cmd);

    //String[] commands = {"system.exe","-get t"};

    BufferedReader stdInput = new BufferedReader(new InputStreamReader(proc.getInputStream()));
    BufferedReader stdError = new BufferedReader(new InputStreamReader(proc.getErrorStream()));

    StringBuffer stdout = new StringBuffer();
    StringBuffer errout = new StringBuffer();

    // read the output from the command
    System.out.println("Here is the standard output of the command:\n");
    String s = null;
    while ((s = stdInput.readLine()) != null) {
        System.out.println(s);
        stdout.append(s);
    }

    // read any errors from the attempted command
    System.out.println("Here is the standard error of the command (if any):\n");
    while ((s = stdError.readLine()) != null) {
        System.out.println(s);
        errout.append(s);
    }

    if (callback == null) {
        return stdInput.toString();
    }

    int exitVal = proc.waitFor();
    callback.onComplete(exitVal == 0, exitVal, errout.toString(), stdout.toString(), cmd);

    return stdInput.toString();
}

public interface CmdExecResult{
    void onComplete(boolean success, int exitVal, String error, String output, String originalCmd);
}

答案 9 :(得分:0)

与此页面上的其他 片段 几乎相同,但只是通过功能整理内容,我们开始... < / p>

String str=shell_exec("ls -l");

Class函数:

public String shell_exec(String cmd)
       {
       String o=null;
       try
         {
         Process p=Runtime.getRuntime().exec(cmd);
         BufferedReader b=new BufferedReader(new InputStreamReader(p.getInputStream()));
         String r;
         while((r=b.readLine())!=null)o+=r;
         }catch(Exception e){o="error";}
       return o;
       }

答案 10 :(得分:0)

如果您在Kotlin上书写,则可以使用:

val firstProcess = ProcessBuilder("echo","hello world").start()
val firstError = firstProcess.errorStream.readBytes().decodeToString()
val firstResult = firstProcess.inputStream.readBytes().decodeToString()

答案 11 :(得分:-1)

尝试阅读运行时的InputStream:

Runtime rt = Runtime.getRuntime();
String[] commands = {"system.exe","-send",argument};
Process proc = rt.exec(commands);
BufferedReader br = new BufferedReader(
    new InputStreamReader(proc.getInputStream()));
String line;
while ((line = br.readLine()) != null)
    System.out.println(line);
}

如果进程正在打印错误输出,您可能还需要读取错误流(proc.getErrorStream())。如果使用ProcessBuilder,则可以将错误流重定向到输入流。

答案 12 :(得分:-1)

Process p = Runtime.getRuntime().exec("ping google.com");

p.getInputStream().transferTo(System.out);

p.getErrorStream().transferTo(System.out);