Verändern des "Environment" innerhalb des processBuilder - Prozesses

wimmerflo

Grünschnabel
Erst mal ein "Hallo Community" von einem Neuling hier !

Nun auch schon gleich zu meiner Frage:

Gibt es eine Möglichkeit die temporären Umgebungsvariablen innerhalb eines Skriptes (Batch, TCL,Perl,...) das von JAVA aus aufgerufen wird, zu verändern ?
Auslesen der Variablen per Ausgabe (echo, puts, ...) an der Shell und BufferedReader / Scanner vom process InputStream seitens JAVA ist mir bekannt. Jedoch würde ich es bevorzugen die Variablen direkt weiter verwenden bzw. ändern zu können, falls dies einfach zu realisieren wäre.

Code:
		ProcessBuilder processBuilder = new ProcessBuilder();
		processBuilder.command(scriptFile.getAbsolutePath());
		processBuilder.directory(scriptFile.getParentFile());
		processBuilder.environment().put("test", "123");

		Process process;
		try {
			process = processBuilder.start();
                ...

Die Variable Test sollte nach Aufruf des Skripts einen andern Wert ("abc") enthalten der vom Skript selbst festgelegt wird.

Vielen herzlichen Dank !

Flo
 
Also laut Doc kannst du auf die Map die über ProcessBuilder.environment() kommt ganz normale Methoden anwenden. Du müsstest also in deinem Script einen Punkt einbauen an dem es sicher auf eine Aktion aus deine Klasse wartet und da der Informationen ausgetauscht werden können.
Allerdings musst du folgendest beachten :
Beim erzeugen einer neuen ProcessBuilder-Instanz wird als Vorlage eine Kopie von System.getenv() herangezogen. Wenn ein Child-Process nun seine Umgebung ändert gilt diese nur für den ChildProcess selbst und das auch nur so lange dieser ALIVE ist *also läuft*.
 
Hallo Spikee !

Danke für deine Antwort.
Jedoch ist mir noch nicht klar, wie ich eine Verbindung zwischen der Map für die Variablen und dem Skript herstellen soll ...
Nur noch mal zum Verständnis:
1. erzeugen einer Variable != Systemvariable (zB: testVariable)
2. erstellen einer ProcessBuilder Instanz mit dem Skript (c:/test.bat)
3. Batch verändert Variable
4. Auslesen der veränderten Variable

wie ausser

set testVariable=abc

kann ich mir hier behelfen ?
Kann ich zB Perl diese Map irgendwie als "Parameter" übergeben ? oder TCL ?

Danke nochmals !
 
Wie gesagt : über die Map
Einfach in dein Code Process.wairFor() einbauen und dann irgendwo in die Batch ein PAUSE. Das bekommst du ja über den Stream mit und kannst dann einfach über Map.get() den aktuellen Wert rausholen ... sollte funktionieren. *Vorher natürlich eine aktuelle map über ProcessBuilder.environment() holen*
 
Hallo Spike !

hier mal mein aktueller "Zustand"

Code:
	public void execBatch(String batchFile) {
		File scriptFile = new File(batchFile);
		ProcessBuilder processBuilder = new ProcessBuilder();
		processBuilder.command(scriptFile.getAbsolutePath());
		processBuilder.directory(scriptFile.getParentFile());
		Map<String, String> x = processBuilder.environment();
		x.put("test", "123");
		System.out.println("Variable test (vorher): " + x.get("test"));
		try {
			Process process = processBuilder.start();
			x = processBuilder.environment();
			System.out.println("Variable test (nachher): " + x.get("test"));
			process.waitFor();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

und hier das Versuchs-Skript:

Code:
@echo off
set test=abc
pause

Bis dato ist die Ausgabe gleich (123) ... liegt es an der Reihenfolge innerhalb des 'try' ?
 
Hmm ...
Also ich hab da jetzt nochmal so drüber nachgedacht. Bevor wir beide uns weiter die Köpfe gegenseitig einhauen weil wir zu keiner Lösung kommen muss ich doch erstmal nachfragen : wozu versuchst du das überhaupt?

btw : Ich habe noch eine zweite Möglichkeit in betracht gezogen, weis aber nicht ob diese überhaupt umsetzbar ist : Pipes. Versuche es einfach mal mit Pipes ... diese kannst du in Java wie normale Streams verwenden ... ob das auf Scriptseite möglich ist weis ich aber nicht. Ist nur so ein nebenbei-Gedanke.
 
Der Plan ist folgender:

Ich habe ein System bestehend aus zB LDAP, SQL, CSV-Dateien usw usf.
Bei der Synchronisation zwischen diesen Systemen soll der Benutzer Felder nach seinen "Wünschen" bearbeiten und verändern können. Dazu habe ich mir überlegt wäre es gut wenn ich die Logik zur Bearbeitung in externe Skripte auslagere ... diese können dann per GUI in JAVA angepasst werden.

Da ich die Werte, die der Benutzer per Skript verändert, aber erst darstellen will (Fehlerkorrektur, falsche Logik in den Skripten etc) sollen die errechneten Werte erst noch ausgelesen werden.

PS: Köpfe einhauen ist momentan nicht lieferbar ... :)
 
Also das versteh ich jetzt erlich gesagt überhaupt nicht warum du dir da so die arbeit machst ?
Du hast das Zauberwort schon gesagt : CSV ... gut .. LDAP kenn ich nun nicht aber SQL *egal ob MySQL oder M$* und Java können CSV ... und da du es ja so dierekt gesagt hast wird LDAP denke ich mal damit auch klar kommen. Und um mit CSV-Daten zu arbeiten brauchts keine externen Scripte oder gar Excel ... das sind lediglich Text-Files deren Datensätze durch Zeilenumbruch und die Werte durch ein Komma oder Simekolon getrennt sind. Das würde ich rein in Java implementieren *zu mal du via SQL-Driver sogar noch dierekt mit der DB kommunizieren kannst*.

Punkto Lieferbarkeit : *flüche*
 
Guten Abend Spikee,

was die einzelnen Quell bzw. Zielsysteme sind und wie man sie in Java anbindet ist soweit eher das geringere Übel. Sind ja auch noch XML-Dateien etc. dabei ... also wie ich die Daten - OHNE - Anpassungen von A) nach B) bekomme ist nicht wild.

Der Punkt ist ja, dass ich zwischen A) und B) noch Aktionen -> durch Skripte <- ausführen lassen möchte.

Beispiel: Der SQL - Server hat Daten wie Vorname, Nachname und Standort. Diese drei Informationen gehen jetzt in ein Skript hinein und werden dort zu Vorname.Nachname@Standort.de (oder was auch immer der Benutzer will). Diese vom Benutzer generierte Information möchte ich nun aus dem Skript auslesen (Properties / Variable) und dann beispielsweise in einen Mail-Server oder in ein ADS / LDAP etc. übertragen.

Jetzt frage ich mich ob es eine Möglichkeit gibt eine Variable zu deklarieren die ich wieder einlesen lassen kann.
 
Ahh ... gut. Ich habs mir durchgelesen und hab auch drüber nachgedacht : wenn es kein Problem ist die verschiedenen Systeme und Daten in Java einzubinden , warum führst du dann das was im Script steht nicht in Java aus ? Oder ist dies aus einem speziellen Grund *zum Beipsiel weil Script in Perl , Ruby oder Python* eben nicht möglich was dich zu diesem Umweg ZWINGT ?
Nun ... nach dem ich seit gestern mich intensiv mal wieder mit diveresen Linux2.6-Distributionen rumgeärgert habe und in meiner Oracle VM V-Box nur OpenSuSE 11.4 erfolgreich zum laufen bekommen habe habe ich dann auch gleich das mal getestet : es ist mir nicht mal unter Linux möglich Umgebungsvariablen nach einer Veränderung durch ein externes Script wieder einzulesen.
Was du jetzt also machen müsstest wäre mit Process.getInput/OutputStream() zu arbeiten und entweder jeden Datensatz einzeln bearbeiten *was zu einer extrem häufigen Ausführung des Scriptes führen würde > schlechtes Design aber am einfachsten umsetzbar* oder sicherstellen das die Datensätze auch so wieder rauskommen wie sie reingegangen sind *Stack-Prinzip*. Wie gesagt : wenn du kannst würde ich versuchen alle Daten in Java zu laden und dann dierekt innerhalb von Java zu verarbeiten und nur die Dinge die man wirklich im externen Script machen muss auslagern. Außerdem gibt es mitlerweile für viele Sprachen auch Engines um diese innerhalb von Java laufen zu lassen. Vielleicht hilft dir das ja weiter.
 
Zurück