Java:有没有办法在执行过程中运行系统命令并打印输出?

2024-09-30 14:29:16 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个python脚本,它需要很长时间才能完成。我想从Java运行它,但也输出脚本在执行时的输出,这样我就可以判断它是否正常运行。在

我搜索过,只找到了在系统命令完成后输出的示例,而不是在执行过程中输出的示例。在

在脚本运行时有什么方法可以做到吗?在

这是我所拥有的

public void doSomething() throws IOException {
    String[] callAndArgs = {"python", "/hi.py"};
    Process p = Runtime.getRuntime().exec(callAndArgs);
    BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
    BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream()));

    String s;
    while ((s = stdInput.readLine()) != null) {
        System.out.println(s);
    }

    while ((s = stdError.readLine()) != null) {
        System.out.println(s);
    }
}

Tags: 脚本示例newreadlinestringoutsystemnull
3条回答

I've searched and only found examples where we output the output after the system command has finished, rather than during its execution.

这很奇怪,因为您的示例应该在执行命令时转储输出。在

您可以尝试直接从InputStream读取,而不是使用BufferedReader,因为在进程退出之前,readLine所需的条件可能无法满足。在

我还建议您直接使用ProcessBuilderover Process,因为除了其他任何东西,它允许您将输出从错误流重定向到输入流,允许您只读取一个流而不是两个。。。在

这也可能是Python的问题,以及它如何刷新输出缓冲区。。。在

例如,与其等待BufferedReader决定何时返回,不如在流发生/被报告时打印流中的每个字符

            ProcessBuilder pb = new ProcessBuilder("test.py");
            pb.redirectError();
            Process p = pb.start();

            InputStream is = null;
            try {
                is = p.getInputStream();
                int in = -1;
                while ((in = is.read()) != -1) {
                    System.out.print((char)in);
                }
            } finally {
                try {
                    is.close();
                } catch (Exception e) {
                }
            }

更新

在进行一点阅读之后,Python似乎在将其发送到stdout之前将其缓冲出来。我不认为您可以在Java端解决这个问题,但是需要改变Python的运行方式或脚本的工作方式。在

有关详细信息,请参见How to flush output of Python print?

不要在while循环中使用#readLine作为条件。相反,请将您的输入流包装在扫描仪中并使用#hasNextLine()

    Scanner in = new Scanner(p.getInputStream());
    while (in.hasNextLine()) {
        System.out.println(in.nextLine());
    }

我设法让它这样工作(注意它需要java7):

package test;
import java.lang.ProcessBuilder.Redirect;

public class Test {

    public static void main(String... args) throws Exception {
        ProcessBuilder pb = new ProcessBuilder("python","/home/foobar/Programming/test/src/test/test.py");
        pb.redirectOutput(Redirect.INHERIT);
        Process p = pb.start();
        p.waitFor();
    }

}

python(请注意,我在python上刷新以使它能够使用系统stdout.flush())

^{pr2}$

注意如果不想在循环中刷新,可以使用以下命令:

ProcessBuilder pb = new ProcessBuilder("python","-u","/home/foobar/Programming/NetBeansProjects/test/src/test/test.py");

在重定向.继承在

Indicates that subprocess I/O source or destination will be the same as those of the current process. This is the normal behavior of most operating system command interpreters (shells).

相关问题 更多 >