Wie man Python-Interpreter ausführt und seine Ausgabe mit Java bekommt?

Ist es möglich, Konsole Ausgabe von Python mit Java zu bekommen? Hier ist ein Beispiel für eine solche Ausgabe:

Python 3.3.4 (v3.3.4:7ff62415e426, Feb 10 2014, 18:13:51) [MSC v.1600 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> 2+2 4 >>> 

Nun ist das Hauptziel, die oben genannte Ausgabe zu erhalten, indem du den Python-Interpreter mit Java aufrufst. Hier ist mein Versuch:

 //... //Irrelevant code omitted ProcessBuilder processBuilder = new ProcessBuilder("cmd"); processBuilder.redirectErrorStream(true); processBuilder.start(); processBuilder.command("python2"); Process pythonProcess = processBuilder.start(); OutputStream outputStream = pythonProcess.getOutputStream(); OutputStreamWriter osw = new OutputStreamWriter(outputStream); osw.write("2+2\r\nquit()\r\n"); osw.flush(); osw.close(); InputStream inputStream = pythonProcess.getInputStream(); BufferedReader bufferedReader = new BufferedReader( new InputStreamReader(inputStream)); String line; while( (line=bufferedReader.readLine())!=null) { System.out.println(line); } //... //Irrelevant code omitted 

Ich verstehe, dass das Aufrufen der Startmethode einen neuen Prozess mit seiner Umgebung für die Ausführung hervorbringt. Das Schreiben von python2 auf den Ausgabestream eines Prozesses python2 zu einem weiteren Prozess. Dies ist, wenn das Problem beginnt. Ich habe nicht in der Lage, einen Weg zu senden, um den Befehl 2+2 an den Python-Interpreter (das ist der Kind Prozess von CMD) anstelle seines Elternprozesses zu senden.

Zusammenfassend: Wie kann ich den Python-Interpreter ausführen, einige Befehle in ihm ausführen und am Ende die Ergebnisse auf die Standardausgabe drucken?

2 Solutions collect form web for “Wie man Python-Interpreter ausführt und seine Ausgabe mit Java bekommt?”

Die Python-ausführbare Datei kann sagen, dass Sie den Befehl nicht interaktiv ausführen. Sobald es realisiert, dass es nicht interaktiv läuft, wird es nicht mehr versuchen, mit Ihnen zu interagieren; Warum stören Sie das Drucken zu stdout oder lesen von stdin wenn niemand dort ist?

Um zu sehen, dass dies wahr ist, würden Sie versuchen, zB "ls" oder "ps" zu laufen und sehen, dass sie in Ihrem Programm arbeiten, aber dann zB "ftp" oder "telnet" oder "python" laufen und sehen, dass das nicht funktioniert Und gibt nichts aus.

Im Linux-Programm ist das Problem, dass die Art und Weise, wie wir Prozesse laufen, keine TTY an sie anhängt. Die Lösung ist, um sie zu glauben, es gibt eine TTY am anderen Ende durch die Schaffung eines PTY.

Trick eine Anwendung in das Denken seine stdin ist interaktiv, nicht eine Pfeife

Auf:

  • Mein Mac OS X 10.9.4 Laptop mit CPython 2.7.5 und Java 1.8.0_05 und
  • Ein Ubuntu 12.04.4 LTS Server mit CPython 2.7.5 und Java 1.7.0_55

Die folgenden Werke, wenn auch in einer sehr hässlichen Art und Weise:

 import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.InputStream; import java.io.InputStreamReader; import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; class Foo { public static void main(String[] args) throws IOException, InterruptedException { // https://stackoverflow.com/questions/1401002/trick-an-application-into-thinking-its-stdin-is-interactive-not-a-pipe // // Using script or unbuffer is the important catch. Without this // step you cannot use stdin in Python interactively, even with // python -u. At least script comes with Linux/Mac OS X, but // unbuffer works fine too. ProcessBuilder pb; switch(System.getProperty("os.name")) { case "Mac OS X": pb = new ProcessBuilder( "/usr/bin/script", "-q", "/dev/null", "/usr/bin/python"); break; default: // Linux pb = new ProcessBuilder( "/usr/bin/script", "-qfc", "/usr/bin/python", "/dev/null"); } // This doesn't make a difference. // pb.redirectErrorStream(true); Process p = pb.start(); char[] readBuffer = new char[1000]; InputStreamReader isr = new InputStreamReader(p.getInputStream()); BufferedReader br = new BufferedReader(isr); int charCount; boolean written = false; while(true) { if (!br.ready() && !written) { // Ugly. Should be reading for '>>>' prompt then writing. Thread.sleep(1000); if (!written) { written = true; OutputStream os = p.getOutputStream(); OutputStreamWriter osw = new OutputStreamWriter(os); BufferedWriter bw = new BufferedWriter(osw); bw.write("2+2"); bw.newLine(); bw.write("quit()"); bw.newLine(); bw.flush(); bw.close(); } continue; } charCount = br.read(readBuffer); if (charCount > 0) System.out.print(new String(readBuffer, 0, charCount)); else break; } } } 

Ich würde es nicht so machen. Stattdessen würde ich Threads verwenden, um interaktiv zu bleiben und zu vermeiden, auf Liest zu blockieren und zu tun, was erwartet, was auf gewisse Aufforderungen wartet, bevor du schreibst. In dem Code oben schlafe ich blind dann Hoffnung auf das Beste.

Allerdings merke ich, dass du Windows benutzt hast, da du "cmd" hast. Ich weiß nicht, wie man PTYs unter Windows erstellt, sorry. Ich denke aber, dass du Expect für Windows bekommen kannst. Unbuffer ist ein Dienstprogramm in Erwartung:

http://expect.sourceforge.net/

Oder probier Cygwin, aber wieder habe ich das nicht getestet

Für weitere Hintergrund auf TTYs und PTYs siehe:

So erstellen Sie eine Pseudo-tty für das Lesen von Ausgabe und Schreiben in die Eingabe

Die Antwort von Asim Ihsan hat die richtige Ursache – Python wird wissen, dass es nicht mit einem interaktiven Terminal verbunden ist und sich nicht so verhält, wie du willst. Sie können Python-Akt im interaktiven Modus, aber durch die Übergabe der -i Flagge, wenn Sie Python starten. Das ist einfacher als das, was Asim vorschlägt. Du solltest einfach Python starten (keine Notwendigkeit der Vermittler von cmd zuerst). Du wirst so etwas verwenden

 ProcessBuilder pb = new ProcessBuilder('python', '-i'); 

Und dann mehr oder weniger wie in der ursprünglichen Frage. Starten Sie den Prozess, erhalten Sie die zugehörigen Streams und lesen und schreiben Sie in die Streams.

  • Wie kann man eine JAR-Datei als Netzwerk-Graph darstellen?
  • Wie man von der url in jython entfernen kann
  • Ich brauche ein einfaches Kommandozeilenprogramm, um XML mit einem XSL Stylesheet zu transformieren
  • Extrahieren von PDF-Anmerkungen / Kommentaren
  • Java entspricht den Python-Wörterbüchern
  • Encoding Probleme beim Ausführen einer App im Docker (Python, Java, Ruby, ...) mit Ubuntu Containern (ascii, utf-8)
  • Sikuli UnsatisfiedLinkError bei der Verwendung von sikuli-script.jar
  • Python-Module von Java aufrufen
  • Konvertieren Sie Java-Byte-Array in Python-Byte-Array
  • Wie man Windows-Authentifizierung Popup in Selen mit Python (plus Java)
  • Auf der Suche nach Datei Traversal Funktionen in Python, die wie Java sind
  • Python ist die beste Programmiersprache der Welt.