我正在使用 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/