I am trying to connect my remote unix machine and execute some ssh commands using a java program.
connection = new Connection(hostname);
connection.connect();
boolean isAuthenticated = connection.authenticateWithPassword(username, password);
if (isAuthenticated == false)
throw new IOException("Authentication failed.");
Session session = connection.openSession();
session.execCommand("sudo su - weblogic");
Here it needs password again & ofcrs, I can't provide because there is no terminal. So created a user.sh file @ my unix user home direcotry (/home/..../bharat) with below content.
echo <mypassword> | sudo -S su - weblogic
sudo -S su - weblogic
but now if I call bash user.sh like below
session.execCommand("bash user.sh");
after logging in with my user in java, it gives below error & could not figure out the resolution for this yet.
sudo: sorry, you must have a tty to run sudo
sudo: sorry, you must have a tty to run sudo
Please help :)
The Response of Send("cd /u02/app/oracle/xyz/admin/domains/11.1.1.9/xxxx_xx_xxx_xxx.domain/shared/logs/xxxx"); is below -
Highlighted Red ==> shows the response, I am getting as of now.
Highlighted Blue ==> Expected response.
Highlighted Green ==> works fine if I send 4 smaller commands by splitting the same command.
As you and @rkosegi say, su
needs a terminal session for the password.
It looks like the Ganymed SSH-2 library in the example? This has an option for a shell session. Clearly you now need to handle reading and writing through stdout and stdin directly though.
For example, with a couple of methods to keep it simpler:
public class SshTerminal {
private Connection connection;
private Session session;
private Reader reader;
private PrintWriter writer;
private String lastResponse;
public SshTerminal(String hostname, String username, String password)
throws JSchException, IOException {
connection = new Connection(hostname);
connection.connect();
boolean isAuthenticated = connection.authenticateWithPassword(username,
password);
if (isAuthenticated == false)
throw new IOException("Authentication failed.");
session = connection.openSession();
session.requestDumbPTY();
session.startShell();
writer = new PrintWriter(session.getStdin());
reader = new InputStreamReader(session.getStdout());
}
public void send(String command) {
writer.print(command + "\n");
writer.flush();
}
public void waitFor(String expected) throws IOException {
StringBuilder buf = new StringBuilder();
char[] chars = new char[256];
while (buf.indexOf(expected) < 0) {
int length = reader.read(chars);
System.out.print(new String(chars, 0, length));
buf.append(chars, 0, length);
}
int echoEnd = buf.indexOf("\n");
int nextPrompt = buf.lastIndexOf("\n");
if (nextPrompt > echoEnd)
lastResponse = buf.substring(echoEnd + 1, nextPrompt);
else
lastResponse = "";
}
public String getLastResponse() {
return lastResponse;
}
public void disconnect() {
session.close();
connection.close();
}
}
This then worked fine:
SshTerminal term = new SshTerminal(host, username, password);
term.waitFor("$ ");
term.send("su -");
term.waitFor("Password: ");
term.send(rootPassword);
term.waitFor("# ");
term.send("ls /root");
term.waitFor("# ");
term.send("cat /file-not-found 2>&1");
term.waitFor("# ");
term.send("cat /var/log/messages");
term.waitFor("# ");
String logFileContent = term.getLastResponse();
term.send("exit");
term.waitFor("$ ");
term.send("exit");
term.disconnect();
String[] lines = logFileContent.split("\n");
for (int i = 0; i < lines.length; i++)
logger.info("Line {} out of {}: {}", i + 1, lines.length, lines[i]);
That includes examples of parsing the lines in a response, and forcing error output through.
Clearly some of the responses there might be different in your environment.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With