Перенаправление выходного потока канала jsch exec в файл с помощью setOutputStream не работает
Я использую канал jsch exec для входа на несколько серверов и запуска нескольких команд. Затем мне нужно захватить выходные данные и сохранить их в файле под названием 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"))));
1 ответ:
Это потому, что
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
. Просто удалите его, и запись файла журнала должна начать работать.
Примечание сбоку: выходной поток будет закрыт по умолчанию с каналом. Поскольку вы повторно используете один и тот же поток для нескольких каналов, вы должны предотвратить это.
Использовать переопределение из аргумента
setOutputStream
с аргументомdontclose
:public void setOutputStream(OutputStream out, boolean dontclose)
Вот так:
channel.setOutputStream(log, true);