Ich verwende die Laufzeit, um Eingabeaufforderungsbefehle von meinem Java-Programm auszuführen. Mir ist jedoch nicht bekannt, wie ich die vom Befehl zurückgegebene Ausgabe erhalten kann.
Hier ist mein Code:
Runtime rt = Runtime.getRuntime();
String[] commands = {"system.exe", "-send" , argument};
Process proc = rt.exec(commands);
Ich habe es versucht, System.out.println(proc);
aber das brachte nichts zurück. Die Ausführung dieses Befehls sollte zwei durch ein Semikolon getrennte Zahlen zurückgeben. Wie könnte ich dies in einer Variablen zum Ausdrucken bringen?
Hier ist der Code, den ich jetzt verwende:
String[] commands = {"system.exe", "-get t"};
Process proc = rt.exec(commands);
InputStream stdIn = proc.getInputStream();
InputStreamReader isr = new InputStreamReader(stdIn);
BufferedReader br = new BufferedReader(isr);
String line = null;
System.out.println("<OUTPUT>");
while ((line = br.readLine()) != null)
System.out.println(line);
System.out.println("</OUTPUT>");
int exitVal = proc.waitFor();
System.out.println("Process exitValue: " + exitVal);
Aber ich bekomme nichts als meine Ausgabe, aber wenn ich diesen Befehl selbst ausführe, funktioniert es gut.
pwd && ls
führt nicht nur eine einzelne Datei aus, wenn Sie dies in einer Shell tun, werden sowohl die/bin/pwd
als auch die/bin/ls
ausführbaren Dateien ausgeführt. Wenn Sie solche Dinge in Java tun möchten, müssen Sie so etwas tun{"/bin/bash","-c", "pwd && ls"}
. Sie haben die Frage wahrscheinlich nicht mehr, aber andere Leute könnten es tun, also dachte ich, ich könnte sie beantworten.stdout
und eine begrenztestderr
Ausgabe. Wenn Sie sie nicht gleichzeitig hören, füllt sich einer von ihnen, während Sie den anderen lesen. Das Programm, das Sie gerade hören, blockiert dann den Versuch, in den gefüllten Puffer zu schreiben, während Ihr Programm am anderen Ende den Versuch blockiert, aus einem Puffer zu lesen, der niemals zurückkehren wirdEOF
. Sie müssen gleichzeitig aus beiden Streams lesen.Ein schnellerer Weg ist folgender:
Welches ist im Grunde eine komprimierte Version davon:
Ich weiß, dass diese Frage alt ist, aber ich poste diese Antwort, weil ich denke, dass dies schneller gehen kann.
quelle
\A
in einem regulären Ausdruck der Beginn eines Strings bedeutet und ich dem Schrägstrich entkommen musste.ProcessBuilder
Lesen und implementieren Sie neben der empfohlenen Verwendung von Senthil alle Empfehlungen von When Runtime.exec () .quelle
ProcessBuilder
wie jetzt empfohlen zweimal verwendet. Mit aProcessBuilder
ist es möglich, die Ausgabe- und Fehlerströme zusammenzuführen, um es einfacher zu machen, beide gleichzeitig zu verwenden.Wenn für die Verwendung bereits Apache commons-io im Klassenpfad verfügbar ist, können Sie Folgendes verwenden:
quelle
Wir können auch Streams verwenden, um die Befehlsausgabe zu erhalten:
quelle
Antwort von @Senthil und @Arend ( https://stackoverflow.com/a/5711150/2268559 ) erwähnt
ProcessBuilder
. Hier ist das BeispielProcessBuilder
mit der Angabe von Umgebungsvariablen und Arbeitsordner für den Befehl:quelle
Zum Zeitpunkt dieses Schreibens können alle anderen Antworten, die Code enthalten, zu Deadlocks führen.
Prozesse haben einen begrenzten Puffer für
stdout
und eine begrenztestderr
Ausgabe. Wenn Sie sie nicht gleichzeitig anhören, füllt sich einer von ihnen, während Sie versuchen, den anderen zu lesen. Beispielsweise könnten Sie darauf warten, gelesen zu werden,stdout
während der Prozess darauf wartet, darauf zu schreibenstderr
. Sie können nicht aus demstdout
Puffer lesen, da dieser leer ist und der Prozess nicht in denstderr
Puffer schreiben kann, weil er voll ist. Sie warten alle für immer aufeinander.Hier ist eine Möglichkeit, die Ausgabe eines Prozesses ohne das Risiko von Deadlocks zu lesen:
Der Schlüssel ist zu verwenden,
ProcessBuilder.redirectErrorStream(true)
derstderr
in denstdout
Stream umleitet . Auf diese Weise können Sie einen einzelnen Stream lesen, ohne zwischenstdout
und wechseln zu müssenstderr
. Wenn Sie dies manuell implementieren möchten, müssen Sie die Streams in zwei verschiedenen Threads verwenden , um sicherzustellen, dass Sie niemals blockieren.quelle
Wenn Sie auf Kotlin schreiben, können Sie Folgendes verwenden:
quelle
Angepasst an die vorherige Antwort:
quelle
Ziemlich genau wie andere Schnipsel auf dieser Seite, aber nur Dinge über eine Funktion organisieren , los geht's ...
Die Klassenfunktion:
quelle
Versuchen Sie,
InputStream
die Laufzeit zu lesen :Möglicherweise müssen Sie auch den Fehlerstrom (
proc.getErrorStream()
) lesen, wenn der Prozess eine Fehlerausgabe druckt. Sie können den Fehlerstrom bei Verwendung auf den Eingabestream umleitenProcessBuilder
.quelle