Programme de la sortie perdu lorsqu'il est passé à travers PsExec

(C'est une question de mon collègue posté d'ailleurs, mais je pensais que je poste ici pour voir si je pourrais toucher un public différent.)

Bonjour à tous,
Je teste la possibilité d'écrire une petite application java la volonté d'utiliser Psexec pour le coup d'envoi de tâches à distance. Dans le cadre de tests de liaison de l'entrée standard stdin et stdout d'un programme java pour psexec je suis tombé sur une drôle de bug.

Mon programme de test est une base echo le programme. Il démarre un thread pour lire l'entrée standard stdin et puis les tuyaux de les lire directement la sortie de retour vers stdout. Lorsqu'il est exécuté sur la machine locale, pas de psexec, il fonctionne à merveille. Exactement comme il se doit.

Cependant, lorsque je l'appelle de PsExec la première fois, l'entrée est acheminée directement dans la sortie standard, il est perdu. Ce qui rend le bug vraiment bizzare, c'est que c'est seulement la première fois que l'entrée est acheminée directement dans stdout qu'il est perdu. Si la Chaîne d'entrée est ajoutée à une autre chaîne, il fonctionne très bien. Soit un littéral de Chaîne ou une variable Chaîne. Toutefois, si la Chaîne d'entrée est directement envoyé vers la sortie standard, il ne fonctionne pas. La deuxième fois, il est envoyé vers la sortie standard, il passe par l'amende et à chaque fois il y a après.

Je suis à une perte complète de ce qui se passe ici. J'ai essayé de tester pour chaque bug je pense. Je suis à court d'idées. Ai-je raté un ou est-ce juste quelque chose à l'intérieur de psexec?

Voici le code en question, c'est en trois classes (dont une qui implémente une interface, qui est une fonction unique interface).

La classe Principale:

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.");
    }
}

Le CReader classe qui est le thread qui lit l'entrée standard 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;
}
}       
}
}

La CEcho classe, qui est la classe que les tuyaux de retour sur la sortie standard:

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");
}
}

Et enfin, voici le programme de la sortie:

>psexec \\remotecomputer "C:\Program Files\Java\jre1.6.0_05\bin\java.exe" -jar "C:\Documents et Settings\testProram.jar" 
PsExec v1.96 - Exécuter les processus à distance 
Copyright (C) 2001-2009 Mark Russinovich 
Sysinternals - www.sysinternals.com 
Le démarrage. 
Démarré avec succès. En attente d'entrée. 
Test 
Reçu caractère: T 
Reçu caractère: e 
Reçu personnage: s 
Reçu caractère: t 
Chaîne d'entrée a fait à fireInputRecieved: Test 
L'ENTRÉE DE DÉMARRAGE REÇU 
L'entrée qui a été reçu est: Test 
C'est une Chaîne, qui a été copié à partir d'un StringBuilder est toString(). 
La sortie proprement à la norme: 
La sortie proprement à la norme de nouveau: 
Test 
Fini les sorties d'entrée: Test 
FIN DE SAISIE REÇU
Dans l'intérêt de la transparence (et donc la Marque ne veut pas être blâmé si j'ai juste fait quelque chose de stupide), je suis le collègue qui a posté la question. Je n'ai aucune idée si je vais juste faire quelque chose de stupide ou si c'est une légitime bug dans psexec. J'ai vraiment un peu de l'espoir c'est l'ex - parce que si c'est le dernier que j'ai à faire beaucoup plus de travail.
qu'il ne soit le nombre de caractères que vous avez saisie ou est-ce le comportement bizarre qu'avec 4-char cordes?
N'a pas d'importance combien de caractères que vous avez entrés.
J'espère que vous trouverez une solution à ce - si donc, assurez-vous de le poster!
Ouais... je souhaite qu'il y ait un moyen de les transférer à d'Alcon... c'est vraiment à sa question, il a juste ne le savais pas comment génial, DONC, a été jusqu'à ce que après que j'ai posté.

OriginalL'auteur mwalling | 2009-08-14