简体   繁体   中英

Copy System.out to a File using Jsch and Java

I am using JSCH with Shell to run multiple commands against a host. everything works, but my question is how can I get System.out and save that to file as well. I am looking to copy not re-direct. I am able to do one or the other but can't do both.

try (OutputStream logOutput = new BufferedOutputStream(new FileOutputStream(outputFilePath))) {
            try (InputStream login = new BufferedInputStream(new FileInputStream(outputFilePath))) {

     JSch jsch = new JSch();
     Session session = jsch.getSession(user, host, 22);
     session.setPassword(password);
     session.setConfig(getProperties());
     session.connect(10 * 1000);
     Channel channel = session.openChannel("shell");
     //channel.setOutputStream(System.out);// I want to activate it as well as the following command
    channel.setOutputStream(logOutPut, true);// I am writing it to file
     try (PipedInputStream commandSource = new PipedInputStream();
           OutputStream commandSink = new PipedOutputStream(commandSource)) {
           CommandSender sender = new CommandSender(commandSink);
           Thread sendThread = new Thread(sender);
           sendThread.start();

           channel.setInputStream(commandSource);
           channel.connect(15 * 1000);
           sendThread.join();
                  if (sender.exception != null) {
                         throw sender.exception;
                             }
                   }
                   channel.disconnect();
                   session.disconnect();

You can make a subclass of FilterOutputStream which writes the same bytes to multiple OutputStreams:

public class MultiplexOutputStream
extends FilterOutputStream {
    private final OutputStream[] streams;

    public MultiplexOutputStream(OutputStream stream,
                                 OutputStream... otherStreams) {
        super(stream);
        this.streams = otherStreams.clone();

        for (OutputStream otherStream : otherStreams) {
            Objects.requireNonNull(otherStream,
                "Null OutputStream not permitted");
        }
    }

    @Override
    public void write(int b)
    throws IOException {
        super.write(b);
        for (OutputStream stream : streams) {
            stream.write(b);
        }
    }

    @Override
    public void write(byte[] bytes)
    throws IOException {
        super.write(bytes);
        for (OutputStream stream : streams) {
            stream.write(bytes);
        }
    }

    @Override
    public void write(byte[] bytes,
                      int offset,
                      int length)
    throws IOException {
        super.write(bytes, offset, length);
        for (OutputStream stream : streams) {
            stream.write(bytes, offset, length);
        }
    }

    @Override
    public void flush()
    throws IOException {
        super.flush();
        for (OutputStream stream : streams) {
            stream.flush();
        }
    }

    @Override
    public void close()
    throws IOException {
        super.close();
        for (OutputStream stream : streams) {
            stream.close();
        }
    }
}

To make use of it in your code:

channel.setOutputStream(new MultiplexOutputStream(logOutput, System.out), true);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM