user5222688
user5222688

Reputation: 39

'nohup mycommand &' via Java code

I am trying to run the following command using Ganymed-SSH2 (ch.ethz.ssh2):

nohup sudo mycommand &

It works when I run directly from command line, but nothing happens when I run it using the Java code below.

Connection connection = new Connection(server);
connection.connect();

if (!connection.authenticateWithPassword(userName, password)) {
throw new IOException("Failed to authenticate with user " + userName + "on host: " + connection.getHostname());
    }

Session session = connection.openSession();
session.requestDumbPTY();

session.execCommand("nohup sudo mycommand &");

session.close();
connection.close();

The command works via the execCommand() method if I exclude the & (but this won't give me my required results), but nothing happens with & there.

Any ideas what is going wrong?

(Note: sudo does not require a password)

Upvotes: 1

Views: 442

Answers (1)

Giuseppe Ricupero
Giuseppe Ricupero

Reputation: 6272

I've found a good hint to solve this issue reading the nohup wikipedia page. Combine nohup and ssh require stdin / std[out|err] to be redirected.

If your server doesn't have Defaults requiretty in /etc/sudoers you can simply use:

sess.execCommand("nohup sudo <yourCommand> 2>&1 >nohup.out </dev/null &");

Entire code:

import ch.ethz.ssh2.*

String hostname    = "localhost";
String username    = "gsus";
File   keyfile     = new File("/home/gsus/.ssh/id_rsa");
String keyfilePass = "";

try {
  Connection conn = new Connection(hostname);
  conn.connect();

  boolean isAuthenticated=conn.authenticateWithPublicKey(username,keyfile,keyfilePass);
  if (isAuthenticated == false)
    throw new IOException("Authentication failed.");

  Session sess=conn.openSession();
  //Don't use this
  //sess.requestDumbPTY();

  sess.execCommand("nohup sudo ping -c 100 www.yahoo.com 2>&1 >nohup.out </dev/null &");

  sess.close();
  conn.close();
}
catch (  IOException e) {
  e.printStackTrace(System.err);
  System.exit(2);
}

If instead your server /etc/sudoers file contains Defaults requiretty (@user5222688) you have to switch using session.startShell()

import ch.ethz.ssh2.*

String hostname    = "localhost";
String username    = "gsus";
File   keyfile     = new File("/home/gsus/.ssh/id_rsa");
String keyfilePass = "";

try {
  Connection conn = new Connection(hostname);
  conn.connect();

  boolean isAuthenticated=conn.authenticateWithPublicKey(username,keyfile,keyfilePass);
  if (isAuthenticated == false)
    throw new IOException("Authentication failed.");

  Session sess=conn.openSession();
  sess.requestPTY("xterm");
  sess.startShell();

  InputStream    stdout = new StreamGobbler(sess.getStdout());
  BufferedReader input  = new BufferedReader(new InputStreamReader(stdout));
  OutputStream   out    = sess.getStdin();
  out.write("nohup sudo <yourCommand> 2>&1 >nohup.out </dev/null &\n".getBytes());
  out.flush();

  while (!input.readLine().contains("stderr")) {
    //Simply move on the stdout of the shell till our command is returned
  }

  sess.close();
  conn.close();
}
catch (IOException e) {
  e.printStackTrace(System.err);
  System.exit(2);
}

Upvotes: 1

Related Questions