Я использую Jsch, и моя задача - войти на сервер и выполнить следующую команду:
sudo "command"
Используя следующий код, я могу успешно подключаться и выполнять команды (без ошибки "sudo : извините, у вас должен быть tty ")
public String runSudo(RemoteHost remoteHost, String[] commands, OperationData operationData, String known_hosts, String id_rsa) {
String result = "";
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
JSch jsch = new JSch();
// Create a JSch session to connect to the server
Session session = null;
try {
session = jsch.getSession(remoteHost.getUsername(), remoteHost.getHost(), remoteHost.getPort());
if (remoteHost.getPassword() != null)
session.setPassword(remoteHost.getPassword());
else{
session.setConfig("PreferredAuthentications", "publickey");
jsch.setKnownHosts(known_hosts);
jsch.addIdentity(id_rsa);
}
session.setConfig(config);
// Establish the connection
session.connect();
logger.debug("Connected...");
for (int k = 0; k < commands.length; k++) {
ChannelExec channel = (ChannelExec) session.openChannel("exec");
channel.setCommand(commands[k]);
OutputStream outputStreamStdErr = new ByteArrayOutputStream();
channel.setErrStream(outputStreamStdErr, true);
channel.setPty(true);
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;
}
result = result + new String(tmp, 0, i);
}
if (channel.isClosed()) {
this.exitStatus += channel.getExitStatus();
break;
}
Thread.sleep(1000);
}
String errors = readInputStream(outputstream2inputstream(outputStreamStdErr));
if (!errors.equals("")) {
operationData.setErrorMessage(errors);
}
channel.getErrStream().close();
channel.disconnect();
}
session.disconnect();
} catch (JSchException e) {
operationData.setErrorMessage(e.getMessage());
logger.error(e.getMessage());
return result;
} catch (IOException e) {
operationData.setErrorMessage(e.getMessage());
logger.error(e.getMessage());
return result;
} catch (InterruptedException e) {
operationData.setErrorMessage(e.getMessage());
logger.error(e.getMessage());
return result;
} finally {
return result;
}
}
Но, используя свойство channel.setPty(true);
, я не могу прочитать поток ошибок, потому что он null
и ошибки отображаются в выводе команды. Вместо этого, если я не использую свойство channel.setPty(true);
, я могу прочитать поток ошибок, но метод возвращает ошибку "sudo: извините, у вас должен быть tty" , которого я хочу избежать.
Может ли кто-нибудь помочь мне использовать поток ошибок и свойство channel.setPty(true);
в одном коде?