Почему вывод из подпроцесса в неправильном порядке? - PullRequest
0 голосов
/ 18 ноября 2010

У меня есть Java-программа, которая выполняет sh в интерактивном режиме в качестве подпроцесса.Ввод копируется из System.in, а вывод - в System.out.Все работает отлично, за исключением того, что при запуске таких команд, как pwd в этой интерактивной оболочке, вывод отображается в неправильном порядке, например:

$ pwd
$ /home/viz/workspace

вместо

$ pwd
/home/viz/workspace
$

Разницазаключается в том, что в первом случае приглашение $ выводится перед выводом из pwd.

Любые идеи, почему это происходит и как это исправить?

Вот код:

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

class StreamCopier implements Runnable {
    private InputStream in;
    private OutputStream out;

    public StreamCopier(InputStream in, OutputStream out) {
        this.in = in;
        this.out = out;
    }

    public void run() {
        try {
            int n;
            byte[] buffer = new byte[4096];
            while ((n = in.read(buffer)) != -1) {
                out.write(buffer, 0, n);
                out.flush();
            }
            out.close();
        }
        catch (IOException e) {
            System.out.println(e);
        }
    }
}

public class Test {
    public static void main(String[] args)
            throws IOException, InterruptedException {
        Process process = Runtime.getRuntime().exec("sh -i +m");
        Thread outThread = new Thread(new StreamCopier(
                process.getInputStream(), System.out));
        outThread.start();
        Thread errThread = new Thread(new StreamCopier(
                process.getErrorStream(), System.err));
        errThread.start();
        Thread inThread = new Thread(new StreamCopier(
                System.in, process.getOutputStream()));
        inThread.start();
        process.waitFor();
        outThread.join();
        errThread.join();
        inThread.join();
    }
}

1 Ответ

1 голос
/ 18 ноября 2010

Поскольку стандартная ошибка и стандартный вывод идут в разные потоки, которые печатают прочитанные данные асинхронно.Это может сработать, если вы перенаправите 2>&1, но я не уверен, что он будет работать с Runtime.exec (может вызвать «файл не найден - 2> & 1»).Таким образом, вы можете создать сценарий оболочки, который вызывает sh и перенаправляет его вывод, и вызывает этот сценарий, используя Runtime.exec:

#!/bin/sh
sh -i +m 2>&1

и

Runtime.exec("customsh"); 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...