2012-03-29 6 views
6

Ich frage mich, gibt es eine Möglichkeit, folgenden Shell-Skript, das auf Benutzereingaben mit Java Runtime-Klasse wartet auf Ausführen?Wie man ein interaktives Shell-Skript mit Java Runtime ausführt?

Ich benutze folgenden Java-Code, um diese Aufgabe zu tun, aber es zeigt nur leere Konsole.

public class TestShellScript { 
public static void main(String[] args) { 

     File wd = new File("/mnt/client/"); 
      System.out.println("Working Directory: " +wd); 
      Process proc = null; 

      try { 
       proc = Runtime.getRuntime().exec("sudo ./test.sh", null, wd); 

      } catch (Exception e) { 
      e.printStackTrace(); 
      } 


} 

}

Sache ist, wenn ich oben Programm ausführen, glaubte ich, es wird einen Shell-Skript ausführen und dass die Shell-Skript wird für Benutzereingaben warten, aber er druckt nur aktuelles Verzeichnis und dann beendet. Gibt es einen Weg dies zu tun oder es ist überhaupt nicht in Java möglich?

Vielen Dank im Voraus

+0

http://stackoverflow.com/questions/4784789/call-interactive -perl-script-from-java –

Antwort

1

Der Grund ist es das aktuelle Verzeichnis druckt und beendet ist, weil Ihre Java-Anwendung beendet. Sie benötigen einen (Gewinde-) Zuhörer an die Eingangs- und Fehlerströme erstellten Prozess hinzuzufügen, und Sie werden wahrscheinlich eine Print auf den Prozess des Ausgangsstroms

Beispiel hinzufügen möchten:



      proc = Runtime.getRuntime().exec(cmds); 
      PrintStream pw = new PrintStream(proc.getOutputStream()); 
      FetcherListener fl = new FetcherListener() { 

       @Override 
       public void fetchedMore(byte[] buf, int start, int end) { 
        textOut.println(new String(buf, start, end - start)); 
       } 

       @Override 
       public void fetchedAll(byte[] buf) { 
       }   
      }; 
      IOUtils.loadDataASync(proc.getInputStream(), fl); 
      IOUtils.loadDataASync(proc.getErrorStream(), fl); 
      String home = System.getProperty("user.home"); 
      //System.out.println("home: " + home); 
      String profile = IOUtils.loadTextFile(new File(home + "/.profile")); 
      pw.println(profile); 
      pw.flush(); 

auszuführen Dazu müssen Sie mein Sourceforge-Projekt herunterladen: http://tus.sourceforge.net/ aber hoffentlich ist das Code-Snippet lehrreich genug, dass Sie sich einfach an J2SE und alles, was Sie sonst noch verwenden, anpassen können.

+0

Kannst du einen Beispielcode oder einen Link einer Webseite posten, der das mit einem Beispiel im Detail erklärt? –

+0

hier ist ein Code, der zeigt: – ControlAltDel

+0

Ich versuchte mit Ihrem Code und Herunterladen Ihrer Quelle von SVN, was passiert, ist es wartet auf Eingabe und ich kann auch Eingabe auf der Konsole eingeben, aber es übergibt nie diese Eingabe Shell-Skript und Programme behalten beim Ausführen. Im Idealfall sollte es sich nach Eingabe des Namens-Shell-Skripts verhalten, wenn Name und Programm ausgedruckt werden sollen. –

1

Wenn Sie einen Java ProcessBuilder verwenden, sollten Sie in der Lage sein, die Input-, Error- und Output-Streams des von Ihnen erstellten Prozesses zu erhalten.

Diese Streams können verwendet werden, um Informationen aus dem Prozess zu erhalten (wie Eingabeaufforderungen), aber sie können auch geschrieben werden, um Informationen direkt in den Prozess zu stellen. Zum Beispiel:

InputStream stdout = process.getInputStream(); 
BufferedReader reader = new BufferedReader (new InputStreamReader(stdout)); 

String line; 
while(true){ 
    line = reader.readLine(); 
    //... 

Das wird Ihnen die Ausgabe aus dem Prozess direkt erhalten. Ich habe es selbst nicht gemacht, aber ich bin mir ziemlich sicher, dass process.getOutputStream() Ihnen etwas gibt, das direkt geschrieben werden kann, um Eingaben an den Prozess zu senden.

1

Das Problem beim Ausführen interaktiver Programme, wie z. B. sudo, von Runtime.exec besteht darin, dass es ihre stdin und stdout an Pipes und nicht an das Konsolengerät anfügt, das sie benötigen. Sie können es durch redirecting the input and output to /dev/tty arbeiten lassen.

Sie können dasselbe Verhalten mit der neuen Klasse ProcessBuilder erreichen, indem Sie die Umleitung mit ProcessBuilder.Redirect.INHERIT einrichten.

0

Beachten Sie unbedingt, dass Sie Eingaben von Java an Ihr Skript senden können. Ich empfehle einen Blick auf Commons Exec jedoch sehr stark an, wenn Sie externe Skripte von Java auszuführen sind:

Commons Exec homepage

Commons Exec API