'nohup mycommand &' 通过 Java 代码

'nohup mycommand &' via Java code

我正在尝试使用 Ganymed-SSH2 (ch.ethz.ssh2) 运行 以下命令:

nohup sudo mycommand &

当我直接从命令行 运行 时它工作,但是当我使用下面的 Java 代码 运行 它时没有任何反应。

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();

如果我排除 &(但这不会给我所需的结果),该命令将通过 execCommand() 方法工作,但那里的 & 没有任何反应。

知道出了什么问题吗?

(注:sudo不需要密码)

我在阅读 nohup 维基百科页面时找到了解决此问题的好提示。结合 nohup 和 ssh 需要重定向 stdin / std[out|err]。

如果您的服务器在 /etc/sudoers 中没有 Defaults requiretty,您可以简单地使用:

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

完整代码:

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);
}

如果您的服务器 /etc/sudoers 文件包含 Defaults requiretty (@user5222688),您必须使用 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);
}