Потеря вывода программы при прохождении через PsExec

(Это вопрос, опубликованный моим коллегойв другом месте, но я думал, чтоЯ бы опубликовал это здесь, чтобы увидеть, смогу ли я попасть в другую аудиторию.)

Привет всем, яЯ тестирую возможность написания небольшого Java-приложения, которое будет использовать Psexec для запуска удаленных заданий. В ходе тестирования связывания stdin и stdout java-программы с psexec я наткнулся на странную ошибку.

Моя тестовая программа - это базовая эхо-программа. Он запускает поток для чтения из стандартного ввода, а затем направляет вывод чтения непосредственно обратно в стандартный вывод. При запуске на локальной машине, а не из psexec, он работает прекрасно. Точно так, как и должно.

Однако, когда я вызываю его из PsExec в первый раз, когда ввод передается напрямую в стандартный вывод, он теряется. Что делает ошибку действительно странной, так это то, что она только в первый раз вводится напрямую в стандартный вывод, когда она теряется. Если входная строка добавляется к другой строке, она работает нормально. Либо строковый литерал, либо строковая переменная. Однако, если входная строка отправляется непосредственно на стандартный вывод, она нене пройти Во второй раз, когда он отправляется на стандартный вывод, он проходит нормально - и каждый раз после.

м в полной растерянности относительно того, чтоздесь происходит Я'Я пытался проверить каждую возможную ошибку, о которой я могу думать. Я'м из идей. Я что-то пропустил или это просто что-то внутри psexec?

Вот код, о котором идет речь, этоS в трех классах (один из которых реализует интерфейс, который взаимодействует с одной функцией).

Основной класс:

public class Main {
    public static void main(String[] args) {
        System.out.println("Starting up.");

        CReader input = new CReader(new BufferedReader(
            new InputStreamReader(System.in)));
        CEcho echo = new CEcho();

        input.addInputStreamListener(echo);
        input.start();

        System.out.println("Successfully started up.  Awaiting input.");
    }
}

Класс CReader, который является потоком, который читает из stdin:

public class CReader extends Thread {
    private ArrayList listeners = 
        new ArrayList();
    private boolean exit = false;
    private Reader in;

    public CReader(Reader in) {
        this.in = in;
    }

    public void addInputStreamListener(InputStreamListener listener) {
        listeners.add(listener);
    }

    public void fireInputRecieved(String input) {

        if(input.equals("quit"))
        exit = true;

        System.out.println("Input string has made it to fireInputRecieved: "
            + input);

        for(int index = 0; index < listeners.size(); index++)
            listeners.get(index).inputRecieved(input);
    }

    @Override
    public void run() {

        StringBuilder sb = new StringBuilder();
        int current = 0, last = 0;

        while (!exit) {
            try {
                current = in.read();
            }
            catch (IOException e) {
                System.out.println("Encountered IOException.");
            }

            if (current == -1) {
                break;
            }

            else if (current == (int) '\r') {
                if(sb.toString().length() == 0) {
                    // Extra \r, don't return empty string.
                    continue;
                }
                fireInputRecieved(new String(sb.toString()));
                sb = new StringBuilder();
            }

            else if(current == (int) '\n') {
                if(sb.toString().length() == 0) {
                    // Extra \n, don't return empty string.
                    continue;
                }
                fireInputRecieved(new String(sb.toString()));
                sb = new StringBuilder();
            }
            else {
                System.out.println("Recieved character: " + (char)current);
                sb.append((char) current);
                last = current;
            }
        }       
    }
}

Класс CEcho, то есть класс, который передает его обратно в stdout:

public class CEcho implements InputStreamListener {
    public void inputRecieved(String input) {
        System.out.println("\n\nSTART INPUT RECIEVED");
        System.out.println("The input that has been recieved is: "+input);
        System.out.println("It is a String, that has been copied from a " +
            "StringBuilder's toString().");
        System.out.println("Outputting it cleanly to standard out: ");
        System.out.println(input);
        System.out.println("Outputting it cleanly to standard out again: ");
        System.out.println(input);
        System.out.println("Finished example outputs of input: "+input);
        System.out.println("END INPUT RECIEVED\n\n");
    }
}

И, наконец, вот вывод программы:

>psexec \\remotecomputer "C:\Program Files\Java\jre1.6.0_05\bin\java.exe" -jar "C:\Documents and Settings\testProram.jar"

PsExec v1.96 - Execute processes remotely
Copyright (C) 2001-2009 Mark Russinovich
Sysinternals - www.sysinternals.com


Starting up.
Successfully started up.  Awaiting input.
Test
Recieved character: T
Recieved character: e
Recieved character: s
Recieved character: t
Input string has made it to fireInputRecieved: Test


START INPUT RECIEVED
The input that has been recieved is: Test
It is a String, that has been copied from a StringBuilder's toString().
Outputting it cleanly to standard out:

Outputting it cleanly to standard out again:
Test
Finished example outputs of input: Test
END INPUT RECIEVED

Ответы на вопрос(13)

Ваш ответ на вопрос