Java Runtime.getRuntime():从执行命令行程序获取输出

|| 我正在使用运行时从Java程序运行命令提示符命令。但是,我不知道如何获得命令返回的输出。 这是我的代码:
Runtime rt = Runtime.getRuntime();

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

Process proc = rt.exec(commands);
我尝试做
System.out.println(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);
但是我没有得到任何输出,但是当我自己运行该命令时,它可以正常工作。
已邀请:
这是要走的路:
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以获得更多详细信息。
ProcessBuilder
将是一个不错的选择。
更快的方法是这样的:
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;
}
我知道这个问题很旧,但是我发布这个答案是因为我认为这可能会更快。
除了按照Senthil的建议使用
ProcessBuilder
之外,请务必阅读并实现When Runtime.exec()不会执行的所有建议。
如果已经在类路径上使用了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());
@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);
我们也可以使用流来获取命令输出:
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);
    }
在撰写本文时,所有其他包含代码的答案都可能导致死锁。 进程对buffer13ѭ和
stderr
输出具有有限的缓冲区。如果您不同时收听它们,那么当您尝试阅读另一种时,它们中的一种会填满。例如,当进程正在等待写入
stderr
时,您可能正在等待从ѭ13读取。您无法从
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()
    {
    }
}
关键是要使用“ 20”,它将“ 14”重定向到“ 13”流中。这使您无需在read13ѭ和
stderr
之间切换就可以读取单个流。如果要手动实现此功能,则必须在两个不同的线程中使用流,以确保永不阻塞。
改编自先前的答案:
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);
}
与此页面上的其他片段几乎相同,但是只是将功能组织起来,所以我们开始...
String str=shell_exec(\"ls -l\");
类函数:
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;
       }
如果您在Kotlin上书写,则可以使用:
val firstProcess = ProcessBuilder(\"echo\",\"hello world\").start()
val firstError = firstProcess.errorStream.readBytes().decodeToString()
val firstResult = firstProcess.inputStream.readBytes().decodeToString()
尝试阅读运行时的“ 29”:
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
,则可以将错误流重定向到输入流。

要回复问题请先登录注册