简短版本:是否可以通过ssh以与远程主机上输出的顺序相同的顺序在远程执行的命令的本地端记录stdout和stderr?如果是这样,怎么样?
长版:
我试图以与远程命令输出的顺序相同的顺序记录远程执行的SSH命令(使用Jsch)的标准和错误输出。换句话说,如果远程命令将“a”写入stdout,然后将“b”写入stderr,然后将“c”写入stdout,我希望客户端(本地)端的日志读取:
一个
b
Ç
以下是我到目前为止的情况。它与我想要的相对接近,但我认为很明显它不能保证客户端的输出顺序正确。
public int exec(String strCommand) throws ExceptionUnableToExecCommand {
JSch jsch = new JSch();
Session session = null;
ChannelExec channel = null;
try {
session = jsch.getSession(user, host, 22);
UserInfo ui = new cyclOps.jsch.UserInfo(password);
session.setUserInfo(ui);
session.connect();
channel = (ChannelExec) session.openChannel("exec");
channel.setCommand(strCommand);
channel.setInputStream(null);
InputStream in = channel.getInputStream();
InputStream err = channel.getErrStream();
channel.connect();
/* getOutput() defined below. */
return this.getOutput(channel, in, err);
} catch (JSchException | IOException e) {
throw new ExceptionUnableToExecCommand("Unable to execute " + strCommand + " " + this.toString(), e);
} finally {
if (channel != null) channel.disconnect();
if (session != null) session.disconnect();
}
}
private int getOutput(ChannelExec channel, InputStream in, InputStream err) throws IOException {
byte[] tmp = new byte[1024];
while(true){
while(in.available() > 0){
int i=in.read(tmp, 0, 1024);
if(i<0)break;
this.sshLogger.logOutputFromSSH(new String(tmp, 0, i));
}
while(err.available() > 0){
int i=err.read(tmp, 0, 1024);
if(i<0)break;
this.sshLogger.logOutputFromSSH(new String(tmp, 0, i));
}
if(channel.isClosed()){
return channel.getExitStatus();
}
try{Thread.sleep(1000);}catch(Exception ee){}
}
}
我想我应该指出这是来自Jsch网站示例的Exec.java的修改版本。
答案 0 :(得分:2)
下面的代码块怎么样?
channel.setCommand(command);
PipedOutputStream pos=new PipedOutputStream();
PipedInputStream pis=new PipedInputStream(pos);
channel.setOutputStream(pos);
channel.setExtOutputStream(pos);
InputStream in=pis;
channel.connect();
答案 1 :(得分:1)
您正在使用单独的流,所以不,您无法保证获得完全相同的输出。
说,你的代码有很多潜在的问题,其中包括: