Użyj przykładu JSch sudo i Channel.setPty do uruchomienia polecenia sudo na zdalnym hoście

Użyłem przykładu JSch Sudo pod następującym linkiem:

http://www.jcraft.com/jsch/examples/Sudo.java.html

I zmienił to trochę i pozbył się wszystkich okien dialogowych, ponieważ muszę użyć go dla instancji EC2 używając PuTTY.

Teraz mój kod wygląda tak:

import com.jcraft.jsch.*;
import java.awt.*;
import javax.swing.*;
import java.io.*;

public class sudo{
  public static void main(String[] arg){
    try{
      JSch jsch=new JSch();

      String host=null;
      if(arg.length>0){
        host=arg[0];
      }

      String privateKey = "my private key.pem";

      jsch.addIdentity(privateKey, "");
      Session session=jsch.getSession("ec2-user", "xx.xx.xx.xx", 22);

      session.setPassword("");
      java.util.Properties config = new java.util.Properties();
      config.put("StrictHostKeyChecking", "no");
      session.setConfig(config);

      session.connect();

      String command="sudo mkdir /data";
      String sudo_pass="";

      Channel channel=session.openChannel("exec");

      // man sudo
      // -S The -S (stdin) option causes sudo to read the password from the
      // standard input instead of the terminal device.
      // -p The -p (prompt) option allows you to override the default
      // password prompt and use a custom one.
      ((ChannelExec)channel).setCommand("sudo -S -p '' "+command);

      InputStream in=channel.getInputStream();
      OutputStream out=channel.getOutputStream();
      ((ChannelExec)channel).setErrStream(System.err);

      channel.connect();

      out.write((sudo_pass+"\n").getBytes());
      out.flush();

      byte[] tmp=new byte[1024];
      while(true){
        while(in.available()>0){
          int i=in.read(tmp, 0, 1024);
          if(i<0)break;
          System.out.print(new String(tmp, 0, i));
        }
        if(channel.isClosed()){
          System.out.println("exit-status: "+channel.getExitStatus());
          break;
        }
        try{Thread.sleep(1000);}catch(Exception ee){}
      }
      channel.disconnect();
      session.disconnect();
    }
    catch(Exception e){
      System.out.println(e);
    }
  }
}

Ale dostaję błąd

przepraszam, musisz mieć tty do uruchomienia sudo

Próbowałem również użyć((ChannelExec) channel).setPty(true) ale mogę uruchomić program raz, ale następnym razem, dla tej samej instancji EC2, otrzymam następujący błąd, ale dla nowej instancji działa dobrze po raz pierwszy.

com.jcraft.jsch.JSchException: Session.connect: java.io.IOException: End of IO Stream Read
sudo mkdir /data
Exception in thread "main" com.jcraft.jsch.JSchException: session is down
        at com.jcraft.jsch.Session.openChannel(Session.java:791)

I wtedy również nie mogłem ssh zdalnego hosta z linii poleceń, jak również.

Czy ktoś może poprowadzić mnie tym, co muszę zrobić, aby biecsudo polecenie na zdalnym hoście.

questionAnswers(3)

yourAnswerToTheQuestion