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 :)
1 Answers
Answers 1
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.
0 comments:
Post a Comment