【问题标题】:'nohup mycommand &' via Java code'nohup mycommand &' 通过 Java 代码
【发布时间】:2015-10-07 09:32:40
【问题描述】:

我正在尝试使用 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 不需要密码)

【问题讨论】:

    标签: java bash ssh nohup


    【解决方案1】:

    阅读nohup wikipedia 页面,我找到了解决此问题的好方法。结合 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);
    }
    

    【讨论】:

    • 越来越近了......但我在我的标准错误中得到了这个; sudo: sorry, you must have a tty to run sudo
    • 尝试从服务器的 /etc/sudoers 中删除 Defaults requiretty (sudo visudo -f /etc/sudoers)
    • @user5222688 我也为需要 tty 的 sudo 环境更新了我的答案
    • 感谢您接受答案:如果对您有用,请考虑投票
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-17
    • 2012-12-12
    • 2013-10-17
    • 1970-01-01
    相关资源
    最近更新 更多