通过PsExec时程序输出丢失 [英] Program output lost when passed through PsExec

查看:42
本文介绍了通过PsExec时程序输出丢失的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

(这是我的同事发布的一个问题,其他地方,但我想我将其张贴在这里,看看是否可以吸引其他观众.)

(This is a question my coworker posted elsewhere, but I thought I'd post it here to see if I could hit a different audience.)

大家好,我正在测试编写一个小型Java应用程序的可能性,该应用程序将使用Psexec启动远程作业.在将Java程序的stdin和stdout绑定到psexec的测试过程中,我遇到了一个奇怪的错误.

Hello all, I'm testing the possibility of writing a small java application the will use Psexec to kick off remote jobs. In the course of testing binding the stdin and stdout of a java program to psexec I came across an odd bug.

我的测试程序是一个基本的回显程序.它启动一个从stdin读取的线程,然后将读取的输出直接通过管道传递回stdout.当在本地计算机上而不是从psexec上运行时,它可以很好地工作.完全正确.

My test program is a basic echo program. It starts a thread to read from stdin and then pipes the read output directly back to stdout. When run on the local machine, not from psexec, it works beautifully. Exactly as it should.

但是,当我第一次从PsExec调用它时,第一次将输入直接通过管道传递到stdout时,它将丢失.使该错误真正令人困惑的原因是,只有第一次将输入直接通过管道输入到stdout时,它才会丢失.如果将输入字符串附加到另一个字符串,则可以正常工作.字符串文字或字符串变量.但是,如果将输入String直接发送到stdout,则不会通过.第二次发送到stdout时,它运行良好-以后每次都进行.

However, when I call it from PsExec the first time the input is piped directly into stdout it is lost. What makes the bug really bizzare is that it is only the first time the input is piped directly into stdout that it is lost. If the input String is appended to another string it works fine. Either a String literal or a String variable. However, if the input String is sent directly to stdout it doesn't go through. The second time it is sent to stdout it goes through fine - and everytime there after.

我对这里发生的事情完全不知所措.我已尝试测试我能想到的每个可能的错误.我没主意了.我是否想念一个,或者这只是psexec内部的内容?

I'm at a complete loss as to what's going on here. I've tried to test for every possible bug I can think of. I'm out of ideas. Did I miss one or is this just something inside psexec?

这是有问题的代码,它位于三个类中(其中一个实现了一个接口,该接口是单个函数接口).

Here is the code in question, it's in three classes (one of which implements an interface which is a single function interace).

主类:

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读取的线程:

The CReader class which is the thread that reads from stdin:

public class CReader extends Thread {
    private ArrayList<InputStreamListener> listeners = 
        new ArrayList<InputStreamListener>();
    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的类:

The CEcho class, which is the class that pipes it back to 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

推荐答案

您是否尝试过将输出重定向到文件(java ...> c:\ output.txt)?这样,您可以仔细检查是否所有内容都将进入stdout并可能被psexec吞噬

have you tried redirecting the output into a file ( java... >c:\output.txt )? this way you could doublecheck if everything is going into stdout and maybe just getting eaten by psexec

这篇关于通过PsExec时程序输出丢失的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆