2016-06-03 14 views
0

Ich habe erfolgreich AutoIt zur Ausführung von Befehlen verwendet, aber ich dachte, ich könnte eine stabilere Implementierung über Runtime bekommen. Auf diese Weise weiß ich, dass die Befehle immer ausgeführt werden und nicht durch Unterbrechungsausnahmen und anderen zufälligen Mist ausgelöst werden. Gibt es etwas in Runtime, von dem ich nicht weiß, dass es keine kontinuierliche Ausführung von Befehlen erlaubt? Hat es keinen Speicher für die Ausgaben früherer Befehle, d. H., Läuft es nicht in einer beständigen Befehlszeile?Ausführen von Befehlen mit Java Runtime

Die folgenden Befehle navigieren zu einem Ordner und führen ein Maven-Skript aus. Wie würde ich das zur Arbeit bringen? Wenn es mehr als 10 weitere Befehle gäbe, würden sie innerhalb desselben Prozesses ausgeführt werden?

sendCommand("cmd.exe cd homepath/plugins"); 
sendCommand("mvn archetype:generate -DarchetypeCatalog=file://homepath/.m2/repository"); 

private static void sendCommand(String text) throws IOException { 
    Runtime.getRuntime().exec(text); 
} 

Antwort

1

Ein paar Dinge.

  1. Sie sollten stattdessen Process und ProcessBuilder verwenden.
  2. Die Befehle müssen nach Argumenten aufgeteilt und in Token aufgeteilt werden.
  3. Wie Sie es geschrieben haben, werden diese beiden Befehle nicht im selben Prozess ausgeführt.
  4. Glücklicherweise unterstützt ProcessBuilder das Ändern des Arbeitsverzeichnisses des Befehls trotzdem.

Als Beispiel:

sendCommand("homepath/plugins", "mvn", "archetype:generate", "-DarchetypeCatalog=file://homepath/.m2/repository"); 

private static void sendCommand(String workingDirectory, String... command) throws IOException { 
    Process proc = new ProcessBuilder(command).directory(new File(workingDirectory)).start(); 
    int status = proc.waitFor(); 
    if (status != 0) { 
     // Handle non-zero exit code, which means the command failed 
    } 
} 

Beachten Sie, wie a) der Befehl aufgeteilt wurde, und b) dass das Arbeitsverzeichnis wird eingeleitet und eingestellt ProcessBuilder.directory(File) verwenden. Dies wird Ihr gewünschtes Verhalten erhalten, aber beachten Sie, dass jeder Befehl weiterhin ein separater Prozess ist und es keine Möglichkeit gibt, sie mit Java zu kombinieren. Sie müssen Maven-Funktionen verwenden, um alle gleichzeitig auszuführen, indem Sie mehrere Build-Ziele angeben.

+0

Was ist damit? http://StackOverflow.com/a/18867097 Es sieht so aus, als ob ich && zwischen den Befehlen hinzufügen kann, um alle innerhalb desselben Prozesses auszuführen? – santafebound

+0

@bluemunch Dies wird alle zu einem einzigen Befehl kombinieren, aber es wird nicht zu einer einzigen Prozess-ID kombiniert. Jetzt * wird * sie alle zu einem einzigen 'java.util.Process' kombinieren. Wenn Sie das mit einem einzigen Prozess meinen, dann funktioniert das '&&' perfekt für Sie. – Brian

2

Laufzeit.exec() gibt eine Prozessinstanz zurück. Rufen Sie waitFor() für dieses Objekt auf, um zu warten, bis es abgeschlossen ist, bevor Sie einen nächsten Befehl ausführen. Sie können mit einem Prozess über seine Methoden getInputStream()/getOutputStream() kommunizieren.

Lesen Sie auch den Javadoc. Für Runtime.exec heißt es "Führt den angegebenen String-Befehl in einem separaten Prozess aus."

+0

Okay, wenn mein Skript hat 20 Befehlszeilen sagen, dann will ich sie alle in einem Prozess Exec? – santafebound

Verwandte Themen