【问题标题】:Java and SSH causing hangsJava 和 SSH 导致挂起
【发布时间】:2017-09-15 22:37:36
【问题描述】:

我正在尝试用 Java 在远程服务器上执行四个命令。由于命令涉及导出,因此我将它们链接到一个命令中:

rm -f nohup.out && export <a few similar commands> && nohup #here I execute a 
startup script#>nohup.out >nohup.out 2>nohup.err </dev/null &

然后我想稍等片刻(大约 30 秒)并从 nohup.out 解析一个 IP 地址。我遇到的问题是程序挂起并且似乎没有断开连接 - 调试代码表明它在下面的代码块中的某处中断,因为它实际上确实成功执行了服务器端命令

如何成功关闭连接?

发送代码,使用JSch,来自本网站上一个upvoted 的解决方案,如下所示。在此之后有一条调试线永远无法到达。

((ChannelExec)channel).setCommand(command);
    InputStream commandOutput = channel.getInputStream();
    channel.connect();
    int readByte = commandOutput.read();

    while(readByte != 0xffffffff)
    //while (true)
    {
       outputBuffer.append((char)readByte);
       readByte = commandOutput.read();
    }

【问题讨论】:

  • 您需要nohup&amp; 做什么?
  • 我运行的服务器端脚本会吐出很多东西,我并不关心——我只关心包含 IP 地址的一行。坦率地说,我对 ssh 了解不多,所以我可能根本不需要 nohup。我的想法是它会抑制输出,并允许 java 程序在不杀死服务器端程序的情况下关闭。我用错了吗?
  • 如果没有 nohup,我能想到的另一个选项是持续监控服务器输出,直到 IP 地址出现
  • 编辑:原来孤立进程是由于正在执行的服务器端脚本出现故障,因此与此问题无关
  • 另见How to read JSch command output? - 它展示了如何正确同时读取标准和错误输出,以允许命令完成并收集包括错误在内的所有输出。跨度>

标签: java ssh jsch


【解决方案1】:

我遇到过类似的问题,我正在阅读其他类型的流(例如 websockets)。大多数时候,它是关于 read() 阻塞并且对中断反应不佳。如果是这种情况,您可能需要强制关闭通道或切换到非阻塞(可能使用 available() 或类似的东西)。

你可以指定你想要的输出流,而不是轮询读取。

这是一个工作示例:

     executor = (ChannelExec) session.openChannel("exec");
        executor.setPty(true);
        executor.setCommand(script);
        executor.setOutputStream(output);
        executor.setErrStream(error);
        executor.connect();
        int errorStatus = -1;

        for (int i = 0; !executor.isClosed(); i++) {
            if (i > 0) {
                long delayMs = (long) (200L * Math.pow(i, 2));
                Thread.sleep(delayMs);
            }
            if ((errorStatus = executor.getExitStatus()) != -1) {
                break;
            }
        }
        LOGGER.debug("Output: {}", output.toString());
        LOGGER.debug("Error:  {}", error.toString());

【讨论】:

  • 这里,输出和错误流是我想要的任何读取流?
  • 是的,唯一的区别是,使用您的方法,您可以按照自己的节奏/轮询阅读,而使用建议的代码,输出将被写入缓冲区。
猜你喜欢
  • 2014-05-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-24
  • 2014-08-14
  • 1970-01-01
相关资源
最近更新 更多