gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 08:41:48 25 4
gpt4 key购买 nike

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

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com