2013-06-27 11 views
5

Meine Anforderung lautet wie folgt:
Ich muss mich mit meinen Zugangsdaten in die Unix-Box einloggen und sobald ich mich eingeloggt habe, muss ich Sudo für andere Benutzer tun. Sobald Sudo erfolgreich ist, muss ich Shell in Nohup aufrufen. Schließen Sie Kanal und Sitzung nach Abschluss der Ausführungen.Mehrere Befehle mit JSch

Ich versuchte den ersten Schritt, der Verbindung mit Sudo Befehl ist, aber ich weiß nicht, wie Shell-Skript nach dem Sudo-Befehl aufrufen.

Im folgenden Code kann ich Sudo-Befehl ausführen, aber nach Sudo Zugriff wie kann ich eine Shell in nohup mit Benutzer masteruser ausführen. Damit die benötigten Dateien meine Shell haben, hat der Besitzer masteruser.

public class SSHUploader { 

    Session session = null; 

    public SSHUploader(){ 

    } 

    public void connect(){ 
    try { 

      JSch jsch = new JSch(); 
      session = jsch.getSession("user", "xxx.xxx.xx.xx", 22); 
      session.setPassword("test"); 
      java.util.Properties config = new java.util.Properties(); 
      config.put("StrictHostKeyChecking", "no"); 
      session.setConfig(config); 
      session.connect(); 
     } catch (Exception ex) { 
      ex.printStackTrace(); 
     } 
    } 

    public void executeCommand(String script) throws JSchException, IOException{ 
     System.out.println("Execute sudo"); 
     String sudo_pass = "test"; 
     ChannelExec channel = (ChannelExec) session.openChannel("exec"); 
     ((ChannelExec) channel).setCommand(script); 

     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) { 
       System.out.println(ee); 
      } 
     } 
     channel.disconnect(); 
     System.out.println("Sudo disconnect"); 
    } 

    public void disconnect(){ 
     session.disconnect(); 
    } 


    public static void main(String... args) throws JSchException, IOException { 

     SSHUploader up = new SSHUploader(); 
     up.connect(); 

     up.executeCommand("sudo -u masteruser bash"); 

     up.disconnect(); 
    } 

} 
+0

Mögliches Duplikat von [So führen Sie mehrere Operationen mit JSch aus] (https://stackoverflow.com/questions/7419513/how-to-perform-multiple-operations-with-jsch) – Gregor

Antwort

12

Für mehrere Befehle nacheinander ausgeführt wird, können Sie eine Befehlsfolge wie unten erstellen:

String script ="pbrun su - user; cd /home/scripts;./sample_script.sh” 

es ausführen und diese Zeichenfolge an Ihrer Methode oben übergeben.

+0

Ehrfürchtig. Ich habe viel Zeit verschwendet, um SSH-Clients/Verbindungen zwischenzuspeichern, nur um es dank dir in weniger als einer Minute zu reparieren. Vielen Dank! – Buffalo

+0

Auch das Hinzufügen von "echo Running script_X; ./script_X" scheint mit mehreren Befehlen sinnvoll zu sein. – Buffalo

+0

Beachten Sie, dass dies * nix Shell-spezifische Lösung ist - es ist weder SSH noch JSch Feature - also auf anderen Systemen (wie Windows), könnte eine andere Syntax benötigt werden. +1 –

0

Die Post kann alt sein, aber ich fand eine andere einfache Möglichkeit, die es Ihnen ermöglicht, die Ausgabe jedes Befehls separat zu retreive. Beachten Sie, dass dieser Code ausgeführt werden muss, sobald die Sitzung geöffnet wurde, wie in den Beispielen gezeigt (http://www.jcraft.com/jsch/examples/Exec.java.html):

for (String command : commands) { 
      ChannelExec channel = (ChannelExec) session.openChannel("exec"); 
      channel.setInputStream(null); 
      channel.setErrStream(System.err); 
      channel.setCommand(command); 
      channel.connect(); 
      printOutput(channel); 
      channel.disconnect(); 
     } 

Wo printOutputchannel.getInpuStream() das Ergebnis des Befehls lesen verwendet.