java - 使用 setOutputStream 将 JSch exec channel 的输出流重定向到文件不起作用

标签 java ssh jsch

我正在使用 JSch exec channel 登录多个服务器并运行一些命令。然后我需要捕获输出并将其存储在名为 log 的文件中。由于某些奇怪的原因,该文件在执行后仍为空白。

try (OutputStream log = new BufferedOutputStream(new FileOutputStream(outputFilePath))) {
    ArrayList<String> lists = new ArrayList<String>();
    lists.add("hostname");
    lists.add("df -l");
    String host ="localhost";

    JSch jsch = new JSch();
    try {
        String user = "user";
        String password = "pass";
        Session session = jsch.getSession(user, host, 22);
        session.setPassword(password);
        session.setConfig(getProperties());
        session.setTimeout(20 * 1000);
        System.out.println(session.getTimeout());
        session.connect();
        if (session.isConnected()) {
            System.out.println(host + " Session Established ");
        }

        for (String elem : lists) {
            Channel channel = session.openChannel("exec");
            channel.setOutputStream(log);

            ((ChannelExec) channel).setCommand(elem);

            channel.setInputStream(null);

            ((ChannelExec) channel).setErrStream(System.err);

            InputStream in = channel.getInputStream();

            channel.connect();

            byte[] tmp = new byte[1024];
            while (true) {
                while (in.available() > 0) {
                    int i = in.read(tmp, 0, 1024);
                    if (i < 0) {
                        break;
                    }
                    System.out.print(new String(tmp, 0, i));
                }
                if (channel.isClosed()) {
                    if (in.available() > 0) {
                        continue;
                    }
                    System.out.println("exit-status: " + channel.getExitStatus());
                    break;
                }
                try {
                    Thread.sleep(1000);
                } catch (Exception ee) {
                }
            }
            channel.disconnect();
        }

        session.disconnect();

程序通过 IDE 控制台显示输出,但输出文件已创建,但仍为空白。

然后我将 system.setOut 设置为一个文件,这阻止了控制台显示更多数据,但 output.txt 文件保持空白。

System.setOut(new PrintStream(new BufferedOutputStream(new FileOutputStream("output.txt"))));

最佳答案

这是因为 getInputStream 覆盖了 setOutputStream 调用。

看看这些方法是如何在 JSch 中实现的(两者最终都会调用 io.setOutputStream):

public void setOutputStream(OutputStream out){
  io.setOutputStream(out, false);
}

public InputStream getInputStream() throws IOException {
  int max_input_buffer_size = 32*1024;
  try {
    max_input_buffer_size =
      Integer.parseInt(getSession().getConfig("max_input_buffer_size"));
  }
  catch(Exception e){}
  PipedInputStream in =
    new MyPipedInputStream(
                           32*1024,  // this value should be customizable.
                           max_input_buffer_size
                           );
  boolean resizable = 32*1024<max_input_buffer_size;
  io.setOutputStream(new PassiveOutputStream(in, resizable), false);
  return in;
}

我假设您实际上不需要基于 InputStream in 的输出读取 block 。只需删除它,日志文件写入就应该开始工作。


旁注:输出流将默认与 channel 一起关闭。当您为多个 channel 重复使用同一个流时,您应该防止这种情况发生。

使用带有 dontclose 参数的 setOutputStream 重写:

public void setOutputStream(OutputStream out, boolean dontclose)

像这样:

channel.setOutputStream(log, true);

关于java - 使用 setOutputStream 将 JSch exec channel 的输出流重定向到文件不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34832844/

相关文章:

c++ - 工具链还是 IDE? (调试问题)

java - 即使服务器的主机 key 存在于known_hosts 文件中,JSch 连接也会失败并显示 UnknownHostKey

java - SFTP 连接器 DH key 错误

Java - 就性能而言,哪个集合最适合这种情况?

java - 在 Windows 10 中使用 jpackage 创建 Windows 包时出现问题?

ssh - 将 SSH key 文件与 Netbeans 一起用于远程开发

linux - ybash 使用 syslog 文件格式中的最新日期

java - Android - 在 html webview 中添加图像但图像不显示

java - Spring Data Rest PATCH 禁止更新特定字段

java - JSch:从跳转服务器登录到目标服务器。跳转服务器要求输入 key 的密码,该 key 接受空字符串