java 输出abcd JAVA 输出当进程k终止时_bash

12345678_0001

首先,我建议更换这条线路。Process process = Runtime.getRuntime ().exec ("/bin/bash");带着线条ProcessBuilder builder = new ProcessBuilder("/bin/bash");builder.redirectErrorStream(true);Process process = builder.start();ProcessBuilder是Java 5中的新版本,使运行外部进程更容易。在我看来,它比Runtime.getRuntime().exec()它允许您将子进程的标准错误重定向到其标准输出中。这意味着你只有一个InputStream读。在此之前,您需要有两个单独的线程,一个从stdout从stderr,以避免在标准输出缓冲区为空(导致子进程挂起)时填充标准错误缓冲区,反之亦然。接下来,循环(其中有两个)while ((line = reader.readLine ()) != null) {

    System.out.println ("Stdout: " + line);}只有在reader,它从进程的标准输出中读取,返回文件结束。只有当bash进程退出。如果目前没有进程的输出,它将不会返回文件末尾。相反,它将等待进程的下一行输出,直到有了下一行才返回。由于在到达此循环之前,您要向进程发送两行输入,如果在这两行输入之后进程尚未退出,则这两个循环中的第一个循环将挂起。它将坐在那里等待另一行被阅读,但它将永远不会有另一行可读。我编译了你的源代码(我现在Windows上,所以我替换了/bin/bash带着cmd.exe,但原则应该是相同的),我发现:输入两行后,出现前两个命令的输出,但是程序挂起,如果我打字,比如说,echo test,然后exit,程序退出了第一个循环,因为cmd.exe进程已经结束。然后,程序请求另一行输入(被忽略),直接跳过第二个循环,因为子进程已经退出,然后退出。如果我输入exit然后echo test,我收到一个IOException抱怨管道被关闭。这是意料之中的-第一行输入导致进程退出,没有地方发送第二行。我在我曾经做过的一个程序中,看到了一个类似于你想要的东西的把戏。这个程序保存了许多shell,在其中运行命令并读取这些命令的输出。使用的技巧是始终写出一个“魔术”行,标记shell命令的输出结束,并使用它来确定发送到shell的命令的输出何时完成。我取下了您的代码,在分配给您的行之后,我替换了所有的代码。writer使用以下循环:w

hile (scan.hasNext()) {
    String input = scan.nextLine();
    if (input.trim().equals("exit")) {
        // Putting 'exit' amongst the echo --EOF--s below doesn't work.
        writer.write("exit\n");
    } else {
        writer.write("((" + input + ") && echo --EOF--) || echo --EOF--\n");
    }
    writer.flush();
    line = reader.readLine();
    while (line != null && ! line.trim().equals("--EOF--")) {
        System.out.println ("Stdout: " + line);
        line = reader.readLine();
    }
    if (line == null) {
        break;
    }}

完成此操作后,我可以可靠地运行几个命令,并将每个命令的输出分别返回给我。两人echo --EOF--发送到shell的行中的命令,以确保命令的输出以--EOF--即使在命令错误的结果中。当然,这种方法也有其局限性。这些限制包括:如果输入一个等待用户输入的命令(例如,另一个shell),则程序似乎挂起,它假设shell运行的每个进程都以换行符结束其输出,如果shell运行的命令恰好写出一行,就会有点混乱。--EOF--.bash如果输入不匹配的文本,则报告语法错误并退出。).这些点对你来说可能并不重要,如果你想把它当作一个预定的任务来运行,那么它将被限制在一条命令或一小部分命令上,而这些命令永远不会以这种病态的方式运行。编辑:在Linux上运行此程序后,改进退出处理和其他小的更改。