当前位置: 首页 > 面试题库 >

通过PsExec时程序输出丢失

柴宝
2023-03-14
问题内容

(这是我的同事在其他地方发布的一个问题,但我认为我应该在这里发布,以查看是否可以吸引其他受众。)

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

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

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

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

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

主类:

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<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的类:

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 \\远程计算机“ C:\ Program Files \ Java \ jre1.6.0_05 \ bin \ java.exe” -jar“ C:\ Documents and Settings \ testProram.jar”

PsExec v1.96-远程执行进程
版权所有(C)2001-2009 Mark Russinovich
Sysinternals-www.sysinternals.com


启动。
成功启动。等待输入。
测试
接收的字符:T
接收的字符:e
接收的字符:s
接收的字符:t
输入字符串使其变为fireInputRecieved:测试


开始输入
已收到的输入是:测试
它是一个字符串,已从StringBuilder的toString()复制。
干净地输出到标准输出:

再次将其干净地输出到标准输出中:
测试
输入的完成的示例输出:测试
收到最终输入

问题答案:

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



 类似资料:
  • FAQs in section [15]: [15.1] 为什么应该用 <iostream> 而不是传统的 <cstdio>? [15.2] 当键入非法字符时,为何我的程序进入死循环? [15.3] 那个古怪的while (std::cin >> foo)语法如何工作? [15.4] 为什么我的输入处理会超过文件末尾? [15.5] 为什么我的程序在第一个循环后,会忽略输入请求呢? [15.6]

  • 我有以下结构: 机器1:Jenkins从机(Windows) 机器2:JMeter机器(Windows) 我想得到什么?机器1从Jenkins接收一些参数(用于JMeter测试)。 因此,性能.bat看起来像这样: 因此,基本上它会创建一个结果文件夹,然后导航到JMeter位置并尝试使用给定值运行性能测试。 问题。PSExec似乎没有按预期执行命令。通过CMD发送3个命令:为结果创建文件夹,导航到

  • 我正在尝试使用pskill.exe杀死在远程PC上运行的java进程,它通过批处理文件运行得很好。但是,它在运行OS进程采样器时不起作用。附上OS采样器截图。 我得到下面的错误信息,如果你能帮助我解决问题,我很感激 线程名称:线程组1-1示例开始时间:2017-06-14 14:25:31英国夏令时加载时间:16连接时间:0延迟时间:0大小以字节为单位:0发送字节:0头大小以字节为单位:0主体大小

  • 问题内容: 这是我的代码。我不确定如何使用返回值退出程序。有任何想法吗?这是我完成任务的最后一步。重要区域标有////////我听到了返回的消息,但是当我将main中的void更改为int时,程序会说main必须为void。 问题答案: 只要您不需要返回自定义退出代码(由所返回的0 除外)并且不启动新线程,就可以通过执行以下操作来终止程序 用你的方法。请注意,没有返回任何值,因此您无需将方法从更改

  • 我使用Maven任务创建了一个Azure管道来构建一组Web应用程序。已创建工件提要,并将所需的[存储库]和[分发管理]部分添加到根pom文件中,如下所示: 管道作业已完成,没有错误。在工件提要中,我可以看到许多在构建期间下载的依赖项,但生成的.war文件不在那里。 知道我错过了什么吗?Maven 构建命令的结果最终会在哪里结束?它不应该是指定的工件源吗? 编辑以添加管道yaml: 触发: 主人

  • 问题内容: 快速提问 如果我已经使用jquery的函数序列化了表单,那么在可以使用jquery的ajax将其发送出去之前,我需要对其进行任何处理吗? 我可以寄出去吗 原样还是我需要对其进行预处理? 并且,在php中我将如何阅读? 问题答案: 最好在这里使用。这会将表单的值转换为简单的字符串,可用作AJAX调用的属性: 假设您使用方法将其发送到PHP ,则可以使用和访问这些值 编辑:您可以使用以下方