ubuntuusers.de

[Java] Kommandozeilen-Befehl innerhalb eines Java-Programms ausführen

Status: Gelöst | Ubuntu-Version: Nicht spezifiziert
Antworten |

dersven

Anmeldungsdatum:
16. August 2005

Beiträge: 792

Wohnort: Kreuzlingen, Schweiz

Hallo.

Ich möchte aus meinem Java-Programm heraus gnuplot dazu veranlassen eine Datei mit Befehlen zu öffnen und auszuführen. Befehle wie "ls" kann ich Problemlos ausführen, nur mit gnuplot klappt es nicht. Es kommt auch keine Fehlermeldung (die müsste ich sehen können; zum test habe ich auch eine fehlerhafte gnuplot-Datei verwendet).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
	public void runGnuplot() {
		String command = "gnuplot '"+this.filePlotfile.getAbsolutePath()+"' ";
		command = "ls -al";				// funktioniert!
		command = "pwd";				// ergibt das korrekte Arbeitsverzeichnis (mit der gnuplot-Datei)
		command = "which gnuplot";		// ergibt: /opt/local/bin/gnuplot
		command = "/opt/local/bin/gnuplot '"+this.filePlotfile.getAbsolutePath()+"'";
		command = "/opt/local/bin/gnuplot 'test.plot'";
		
		System.out.println("Try to run GnuPlot for the file: "+ this.filePlotfile.getAbsolutePath());
		System.out.println("Command used:                    "+ command);
		
		Runtime r = Runtime.getRuntime();
		Process p;
		BufferedReader read;
		
		try {
			p = r.exec(command);
			read = new BufferedReader(new InputStreamReader(p.getInputStream()));
			
			String zeile;
			while((zeile = read.readLine())!=null){
				System.err.println("GnuPlot execution ERROR: " + zeile);
			}
			
		} catch (IOException e) {
			System.err.println("ERROR while executing gnuplot command.");
			e.printStackTrace();
		}
		
		System.out.println("Done");
		
	}

Hat jemand eine erklärung dafür?

Wenn ich den Befehl der für die Ausführungs erzeugt wird, direkt ins Terminal eingebe, klappt alles ohne Probleme.

Grüße und Danke.

Greebo

Avatar von Greebo

Anmeldungsdatum:
21. November 2006

Beiträge: 3443

Wohnort: 97070 Würzburg

dersven schrieb:

Es kommt auch keine Fehlermeldung (die müsste ich sehen können; zum test habe ich auch eine fehlerhafte gnuplot-Datei verwendet).

Sooo? Ich sehe nicht, dass du dem Stream von getErrorStream() ausliest. Sollte dort was ausgeworfen aber nicht gelesen werden, könnte das nach volllaufen des entsprechenden Buffers auch die Anwendung blockieren.

dersven

(Themenstarter)

Anmeldungsdatum:
16. August 2005

Beiträge: 792

Wohnort: Kreuzlingen, Schweiz

In der Tat, danke greebo.

Das Problem liegt daran, dass die Datei nicht geöffnet werden kann, weil leerzeichen im Absoluten Pfad der Datei sind. Ich dachte dass ich das von vornherein umgegangen habe, dadurch dass ich es in hard-qoutes gesetzt habe. aber diese toll exec()-Methode löscht diese einfach, egal wie ich aich die escape (naja, mein maximum war: \\\' ).

Also sollte die Frage wohl eher lauten:

Wie kann ich Anführungszeichen verwenden, die nicht von der exec()-Methode gelöscht werden?

Grüße

Greebo

Avatar von Greebo

Anmeldungsdatum:
21. November 2006

Beiträge: 3443

Wohnort: 97070 Würzburg

Eigentlich gibt es dafür auch eine andere Methode.

Process exec(String[] cmdarray) Executes the specified command and arguments in a separate process. Da brauchst du das Maskierungsgehampel nicht.

Ansonsten fleissig in 2er Schritten "\" vorhängen.

dersven

(Themenstarter)

Anmeldungsdatum:
16. August 2005

Beiträge: 792

Wohnort: Kreuzlingen, Schweiz

Greebo schrieb:

Eigentlich gibt es dafür auch eine andere Methode.

Process exec(String[] cmdarray) Executes the specified command and arguments in a separate process. Da brauchst du das Maskierungsgehampel nicht.

Ansonsten fleissig in 2er Schritten "\" vorhängen.

1
2

String[] command = {"gnuplot", this.filePlotfile.getAbsolutePath()};

damit klappt es, auch wenn Leerzeichen im Pfadnamen vorkommen.

Das mit dem escapen hat nicht geklappt.

Ich hoffe mal, das es keine Probleme gibt, wenn ein dateiname den namen eines Programmes trägt. Meine Vorstellung ist, das die exec()-Methode schaut, welche Name das Programm sein muss, und was die Parameter sind.

Greebo

Avatar von Greebo

Anmeldungsdatum:
21. November 2006

Beiträge: 3443

Wohnort: 97070 Würzburg

Anführungszeichen ist ein Mechanismus diverser CLI um Feldgrenzen abzustecken, Java dürfte eher nen passenden Befehl aus der System-API verwenden und die Parameter entsprechend als bereits getrennte Felder übergeben.

Marc_BlackJack_Rintsch Team-Icon

Ehemalige
Avatar von Marc_BlackJack_Rintsch

Anmeldungsdatum:
16. Juni 2006

Beiträge: 4686

Wohnort: Berlin

@dersven: Interessante Vorstellung. Das das erste Element immer als auszuführender Befehl verwendet und alle folgenden immer als Argumente für diesen Befehl, kannst Du Dir nicht vorstellen!?

dersven

(Themenstarter)

Anmeldungsdatum:
16. August 2005

Beiträge: 792

Wohnort: Kreuzlingen, Schweiz

Marc 'BlackJack' Rintsch schrieb:

@dersven: Interessante Vorstellung. Das das erste Element immer als auszuführender Befehl verwendet und alle folgenden immer als Argumente für diesen Befehl, kannst Du Dir nicht vorstellen!?

Doch, dass ist derzeit meine Vorstellung. und dass z.B. nach einem pipe-Sysmbol auch ein neuer befehl kommt

Greebo

Avatar von Greebo

Anmeldungsdatum:
21. November 2006

Beiträge: 3443

Wohnort: 97070 Würzburg

Das Pipezeichen ist auch eine Spezialität des entsprechenden CLI... sowas wird weder von Java noch von der nachgeschalteten Systemfunktion interpretiert. Du musst wirklich zwischen Programmaufrufen und Shell-BuiltIns unterscheiden. Wenn du sowas nutzen willst, rufe ne geeignete Shell auf und gib deine Befehlfolge mit, bzw. interpretiere selbst und konkatiniere die entsprechenden I/O-Streams geeignet. Bei WP gibts nen Beispiel wie sowas in C aussehen würde Pipe_(Informatik)

Antworten |