2013-03-12 23 views
16

Ich muss einen Befehl am Terminal in Fedora 16 von einem JAVA-Programm ausführen. Ich versuchte mitWie führe ich einen Befehl am Terminal von Java-Programm?

aber dies öffnet nur das Terminal, ich bin nicht in der Lage, einen Befehl auszuführen.

Ich habe auch versucht dies:

OutputStream out = null; 
Process proc = new ProcessBuilder("xterm").start(); 
out = proc.getOutputStream(); 
out.write("any command".getBytes()); 
out.flush(); 

, aber ich kann immer noch nur das Terminal öffnen, aber den Befehl nicht ausgeführt werden kann. Irgendwelche Ideen, wie es geht?

+1

Haben Sie 'Runtime.getRuntime() versucht.exec (); 'Sie brauchen' xterm' nicht zu öffnen, um Ihr Terminal zu öffnen. –

+0

Sie sollten 'sh -s' versuchen, und Sie können den Code verwenden, den Sie geschrieben haben, die Shell wird die Befehle aus dem Stream akzeptieren, oder' sh -c ', und der in der Argument wird ausgeführt. – ppeterka

Antwort

22

Sie müssen sie laufen mit bash ausführbar wie folgt aus:

Runtime.getRuntime().exec("/bin/bash -c your_command"); 

Update: Wie xav vorgeschlagen, ist es ratsam, ProcessBuilder stattdessen zu verwenden:

String[] args = new String[] {"/bin/bash", "-c", "your_command", "with", "args"}; 
Process proc = new ProcessBuilder(args).start(); 
+2

Die Verwendung von 'Runtime.exec()' wird jetzt abgeraten: Verwenden Sie stattdessen ProcessBuilder (http://docs.oracle.com/javase/7/docs/api/java/lang/Runtime.html#exec%28java. lang.String [],% 20java.lang.String [],% 20java.io.File% 29) – xav

+0

Das hat bei mir nicht funktioniert. Überprüfen Sie meine Antwort unten. –

6

Sie don‘ t muss tatsächlich einen Befehl von einer XTM-Sitzung ausführen, Sie können es direkt ausführen:

Wenn der Prozess interaktiv mit dem Eingangsstrom reagiert, und Sie wollen Werte injizieren, dann tun, was Sie taten, bevor:

OutputStream out = proc.getOutputStream(); 
out.write("command\n"); 
out.flush(); 

Sie die ‚\ n‘ am Ende nicht vergessen, obwohl als Die meisten Apps verwenden es, um das Ende der Eingabe eines einzelnen Befehls zu identifizieren.

4

Wie andere sagten, können Sie Ihr externes Programm ohne xterm ausführen. Wenn Sie es jedoch in einem Terminalfenster z. Damit der Benutzer mit ihm interagieren kann, können Sie mit xterm das Programm angeben, das als Parameter ausgeführt werden soll.

xterm -e any command 

In Java-Code wird daraus:

String[] command = { "xterm", "-e", "my", "command", "with", "parameters" }; 
Runtime.getRuntime().exec(command); 

Oder mit Process:

String[] command = { "xterm", "-e", "my", "command", "with", "parameters" }; 
Process proc = new ProcessBuilder(command).start(); 
+0

Die Verwendung von 'Runtime.exec()' wird jetzt abgeraten: Verwenden Sie stattdessen ProcessBuilder (http://docs.oracle.com/javase/7/docs/api/java/lang/Runtime.html#exec%28java. lang.String [],% 20java.lang.String [],% 20java.io.File% 29) – xav

+0

Bearbeitete ProcessBuilder-Variante in. Der Kommentar in der Dokumentation bezieht sich auf ProcessBuilder, der bevorzugt Prozesse mit "modifizierter Umgebung" startet , die in diesem Fall nicht verwendet wird. Wie auch immer, die Hauptaufgabe meiner Antwort ist die Aufnahme der Ausführung des Befehls in xterm. – user1252434

11

Ich stimme für Karthik T Antwort. Sie müssen kein Terminal zum Ausführen von Befehlen öffnen.

Zum Beispiel

// file: RunShellCommandFromJava.java 
import java.io.BufferedReader; 
import java.io.InputStreamReader; 

public class RunShellCommandFromJava { 

    public static void main(String[] args) { 

     String command = "ping -c 3 www.google.com"; 

     Process proc = Runtime.getRuntime().exec(command); 

     // Read the output 

     BufferedReader reader = 
       new BufferedReader(new InputStreamReader(proc.getInputStream())); 

     String line = ""; 
     while((line = reader.readLine()) != null) { 
      System.out.print(line + "\n"); 
     } 

     proc.waitFor(); 

    } 
} 

Der Ausgang:

$ javac RunShellCommandFromJava.java 
$ java RunShellCommandFromJava 
PING http://google.com (123.125.81.12): 56 data bytes 
64 bytes from 123.125.81.12: icmp_seq=0 ttl=59 time=108.771 ms 
64 bytes from 123.125.81.12: icmp_seq=1 ttl=59 time=119.601 ms 
64 bytes from 123.125.81.12: icmp_seq=2 ttl=59 time=11.004 ms 

--- http://google.com ping statistics --- 
3 packets transmitted, 3 packets received, 0.0% packet loss 
round-trip min/avg/max/stddev = 11.004/79.792/119.601/48.841 ms 
+0

aber wenn das Ergebnis der Befehlsausführung ist langwieriges Protokoll dann funktioniert diese readLine Sache überhaupt nicht, wie man es auch liest? –

+0

@YashAgrawal Können Sie den Befehl (oder einen ähnlichen Befehl) angeben, der ein langes Protokoll generiert, damit ich dieses Programm erneut testen kann? –

+0

ich kann es hier nicht posten, weil es ein sehr langes Protokoll während der Ausführung von hadoop-Befehlen für ex: /hadoop.../bin/hdfs jar some.jar/input/output –

1

Ich weiß nicht, warum, aber aus irgendeinem Grund, die "/ bin/bash" Version nicht für mich arbeiten . Stattdessen ist die einfachere Version gearbeitet, nach dem here at Oracle Docs.

String[] args = new String[] {"ping", "www.google.com"}; 
Process proc = new ProcessBuilder(args).start(); 
1

Ich weiß, diese Frage ziemlich alt gegebenen Beispiel ist, aber hier ist eine library, die die Process api kapselt.

Verwandte Themen