Gültigkeit von Variablen in Batch-Dateien
Lokale - Globale - Variable
Guten Tag allerseits,
ich schlage mich mit folgendem Problem herum, das ich durch Experimentieren nicht lösen kann:
Ich leite eine Batchdatei mittlerer Größe (ich nenne sie hier "eins.bat") mit 'SetLocal EnableDelayedExpansion' ein, weil die meisten Variablen hier nur intern (LOKAL) von Bedeutung sind. Ich würde gerne aber EINE EINZIGE davon in den Bereich GLOBALER Variablen "hinüberretten", um sie auch nach Ende der Batchprozedur noch einmal zu verwenden. Ich kriege das aber nicht gebacken, muß auch gestehen daß ich die Auswirkungen von 'SetLocal ... ' leider nicht richtig verstanden habe.
Hat jemand bitte einen Tip für mich ?
Dazu möchte ich eine ergänzende Verständnisfrage stellen:
Wenn ich aus obiger Batchdatei ("eins.bat") eine weitere ("zwei.bat") per CALL aufrufe, dann bleiben zuvor LOKAL definierte Variable - nach meiner Beobachtung - zunächst auch in "zwei.bat" gültig. Ich kann sie aus "zwei.bat" heraus durchaus in eine Protokolldatei "zwei.txt" hineinschreiben.
Es gelingt offenbar aber nicht, diese Variable aus "zwei.bat" mit einem SET-Befehl GLOBAL zu verankern.
Es funkioniert: echo %korrzeit%>zwei.txt
Aber NICHT: SET kor1zeit=%korrzeit%
Was mach ich da wohl verkehrt, - oder muß ich die ganze Sache völlig anders aufziehen?
Danke im Voraus und beste Grüße
Jürgen
Guten Tag allerseits,
ich schlage mich mit folgendem Problem herum, das ich durch Experimentieren nicht lösen kann:
Ich leite eine Batchdatei mittlerer Größe (ich nenne sie hier "eins.bat") mit 'SetLocal EnableDelayedExpansion' ein, weil die meisten Variablen hier nur intern (LOKAL) von Bedeutung sind. Ich würde gerne aber EINE EINZIGE davon in den Bereich GLOBALER Variablen "hinüberretten", um sie auch nach Ende der Batchprozedur noch einmal zu verwenden. Ich kriege das aber nicht gebacken, muß auch gestehen daß ich die Auswirkungen von 'SetLocal ... ' leider nicht richtig verstanden habe.
Hat jemand bitte einen Tip für mich ?
Dazu möchte ich eine ergänzende Verständnisfrage stellen:
Wenn ich aus obiger Batchdatei ("eins.bat") eine weitere ("zwei.bat") per CALL aufrufe, dann bleiben zuvor LOKAL definierte Variable - nach meiner Beobachtung - zunächst auch in "zwei.bat" gültig. Ich kann sie aus "zwei.bat" heraus durchaus in eine Protokolldatei "zwei.txt" hineinschreiben.
Es gelingt offenbar aber nicht, diese Variable aus "zwei.bat" mit einem SET-Befehl GLOBAL zu verankern.
Es funkioniert: echo %korrzeit%>zwei.txt
Aber NICHT: SET kor1zeit=%korrzeit%
Was mach ich da wohl verkehrt, - oder muß ich die ganze Sache völlig anders aufziehen?
Danke im Voraus und beste Grüße
Jürgen
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 28400
Url: https://administrator.de/contentid/28400
Ausgedruckt am: 22.11.2024 um 06:11 Uhr
7 Kommentare
Neuester Kommentar
Hi,
jede Shell hat sein eigenes Environment. Wenn du eine Variable in einer Batch definierst und aus der Batch eine zweite Batch aufrufts (=2. Shell) dann ist diese Variable im Environment der 2. Batch vorhanden. Wenn Du im 2. Batch 1 Variable hinzufügst, bekommt das die erste Batch nicht mit.
Du hast 2 Alternativen:
aufruf der 2. Batch über
for /f "usebackq tokens=*" %%i in ('cmd /c zweit.bat variable1') do set korr1zeit = %%i
wenn Du in zweit.bat "echo korrzeit" als letzte Zeile einaust
oder
for /f "tokens=*" %%i in (zwei.txt) do set korr1zeit=%%i
oder die baust die 2. Batch als Prodezur in die erste Batch ein
eins.bat
...
...
...
set korr1zeit=%date%
call :zwei %korr1zeit%
set korr1zeit=%korrzeit%
...
...
...
goto ende
:zwei
set uerbergeben=%* (fängt auch leerzeichen ein)
rem mach was mit uebergeben
set korrzeit=Ergebnis der Berechnung
goto ende
da hast Du die Variablen in einer Shell
Müsste rein aus dem Gedächnis heraus so funktionieren.
Grüße
Dieter
jede Shell hat sein eigenes Environment. Wenn du eine Variable in einer Batch definierst und aus der Batch eine zweite Batch aufrufts (=2. Shell) dann ist diese Variable im Environment der 2. Batch vorhanden. Wenn Du im 2. Batch 1 Variable hinzufügst, bekommt das die erste Batch nicht mit.
Du hast 2 Alternativen:
aufruf der 2. Batch über
for /f "usebackq tokens=*" %%i in ('cmd /c zweit.bat variable1') do set korr1zeit = %%i
wenn Du in zweit.bat "echo korrzeit" als letzte Zeile einaust
oder
for /f "tokens=*" %%i in (zwei.txt) do set korr1zeit=%%i
oder die baust die 2. Batch als Prodezur in die erste Batch ein
eins.bat
...
...
...
set korr1zeit=%date%
call :zwei %korr1zeit%
set korr1zeit=%korrzeit%
...
...
...
goto ende
:zwei
set uerbergeben=%* (fängt auch leerzeichen ein)
rem mach was mit uebergeben
set korrzeit=Ergebnis der Berechnung
goto ende
da hast Du die Variablen in einer Shell
Müsste rein aus dem Gedächnis heraus so funktionieren.
Grüße
Dieter
Nö,
auch wenn die Antwort geholfen hat... soooo umständlich und unlogisch ist Batch nun auch nicht.
Zur Verdeutlichung zwei Mini-Bätche:
:----snipp Batch1.bat
@echo off & setlocal
Set "AAAA=AAAA LOCAL gesetzt in Batch 1"
Set "BBBB=BBBB LOCAL gesetzt in Batch 1"
Echo ---in Batch1.bat ---gesetzte Variablen:
Set AAAA & Set BBBB
Echo ---in Batch1.bat --- Rufe "Batch2.bat AAAA"
Call Batch2.bat AAAA
echo ---wieder in Batch1.bat---- Variablen jetzt:
Set AAAA & Set BBBB
:----snapp Batch1.bat
:----snipp Batch2.bat
@echo off & setlocal
Echo In Batch2... überprüfe gesetzte Variablen "AAAA"/"BBBB"
Echo ---------Selbst noch nichts gesetzt...
Set AAAA & Set BBBB
Echo Set "AAAA=CCCC Lokaler Wert gesetzt in Batch2"
Set "AAAA=!!!!!!! Neuer Wert gesetzt in Batch2"
Echo Set "BBBB=!!!!!!! Lokaler Wert gesetzt in Batch2"
Set "BBBB=!!!!!!! Lokaler Wert gesetzt in Batch2"
Echo --------------Werte innerhalb von Batch2:
Set AAAA & Set BBBB
::Endlocal & Set "%1=!!! Auch Neu" & Set "BBBB=%BBBB%"
:----snapp Batch2.bat
Batch1 setzt zwei Variablen INNERHALB einer Setlocal-Struktur.
Batch zwei wird gerufen und verwendet die gleichen Variablennamen.
$cmd$batch1
---in Batch1.bat ---gesetzte Variablen:
AAAA=AAAA LOCAL gesetzt in Batch 1
BBBB=BBBB LOCAL gesetzt in Batch 1
---in Batch1.bat --- Rufe "Batch2.bat AAAA"
In Batch2... überprüfe gesetzte Variablen "AAAA"/"BBBB"
Selbst noch nichts gesetzt...
AAAA=AAAA LOCAL gesetzt in Batch 1
BBBB=BBBB LOCAL gesetzt in Batch 1
Set "AAAA=CCCC Lokaler Wert gesetzt in Batch2"
Set "BBBB=!!!!!!! Lokaler Wert gesetzt in Batch2"
Werte innerhalb von Batch2:
AAAA=!!!!!!! Neuer Wert gesetzt in Batch2
BBBB=!!!!!!! Lokaler Wert gesetzt in Batch2
---wieder in Batch1.bat---- Variablen jetzt:
AAAA=AAAA LOCAL gesetzt in Batch 1
BBBB=BBBB LOCAL gesetzt in Batch 1
> Erwähnenswert: Die Variablen AAAA und BBBB sind in Batch2 zwar bekannt,
aber Batch2 kann diese nicht so mit neuen Werten füllen, dass es für Batch1 gilt.
Wenn ich aber die auskommentierte Zeile ":: Endlocal &..." entkommentiere, geht das.
Ergebnis dann:
$cmd$batch1
---in Batch1.bat ---gesetzte Variablen:
AAAA=AAAA LOCAL gesetzt in Batch 1
BBBB=BBBB LOCAL gesetzt in Batch 1
---in Batch1.bat --- Rufe "Batch2.bat AAAA"
In Batch2... überprüfe gesetzte Variablen "AAAA"/"BBBB"
Selbst noch nichts gesetzt...
AAAA=AAAA LOCAL gesetzt in Batch 1
BBBB=BBBB LOCAL gesetzt in Batch 1
Set "AAAA=CCCC Lokaler Wert gesetzt in Batch2"
Set "BBBB=!!!!!!! Lokaler Wert gesetzt in Batch2"
Werte innerhalb von Batch2:
AAAA=!!!!!!! Neuer Wert gesetzt in Batch2
BBBB=!!!!!!! Lokaler Wert gesetzt in Batch2
---wieder in Batch1.bat---- Variablen jetzt:
AAAA=!!! Auch Neu
BBBB=!!!!!!! Lokaler Wert gesetzt in Batch2
Beide Syntax-Varianten habe ich auch in Produktiv-Bätchen im Einsatz.
Wem es jetzt einleuchtet, dass auch eine Anweisung wie 'Set "BBBB=%BBBB%"' Sinn machen kann, der hat es verstanden.
Lasst Euch also NICHT solche Anweisungen von übereifrigen Praktikanten wieder rauslöschen.
Ebenfalls elegant bei mehreren "global bekanntzumachenden Variablen" ist die Zeile:
Endlocal & for %%i in ("var1=%var1%" "var2=%var2%" ..) do set %%i
Alles klar? *gg
Schönes Wochenende
Biber
auch wenn die Antwort geholfen hat... soooo umständlich und unlogisch ist Batch nun auch nicht.
Zur Verdeutlichung zwei Mini-Bätche:
:----snipp Batch1.bat
@echo off & setlocal
Set "AAAA=AAAA LOCAL gesetzt in Batch 1"
Set "BBBB=BBBB LOCAL gesetzt in Batch 1"
Echo ---in Batch1.bat ---gesetzte Variablen:
Set AAAA & Set BBBB
Echo ---in Batch1.bat --- Rufe "Batch2.bat AAAA"
Call Batch2.bat AAAA
echo ---wieder in Batch1.bat---- Variablen jetzt:
Set AAAA & Set BBBB
:----snapp Batch1.bat
:----snipp Batch2.bat
@echo off & setlocal
Echo In Batch2... überprüfe gesetzte Variablen "AAAA"/"BBBB"
Echo ---------Selbst noch nichts gesetzt...
Set AAAA & Set BBBB
Echo Set "AAAA=CCCC Lokaler Wert gesetzt in Batch2"
Set "AAAA=!!!!!!! Neuer Wert gesetzt in Batch2"
Echo Set "BBBB=!!!!!!! Lokaler Wert gesetzt in Batch2"
Set "BBBB=!!!!!!! Lokaler Wert gesetzt in Batch2"
Echo --------------Werte innerhalb von Batch2:
Set AAAA & Set BBBB
::Endlocal & Set "%1=!!! Auch Neu" & Set "BBBB=%BBBB%"
:----snapp Batch2.bat
Batch1 setzt zwei Variablen INNERHALB einer Setlocal-Struktur.
Batch zwei wird gerufen und verwendet die gleichen Variablennamen.
$cmd$batch1
---in Batch1.bat ---gesetzte Variablen:
AAAA=AAAA LOCAL gesetzt in Batch 1
BBBB=BBBB LOCAL gesetzt in Batch 1
---in Batch1.bat --- Rufe "Batch2.bat AAAA"
In Batch2... überprüfe gesetzte Variablen "AAAA"/"BBBB"
Selbst noch nichts gesetzt...
AAAA=AAAA LOCAL gesetzt in Batch 1
BBBB=BBBB LOCAL gesetzt in Batch 1
Set "AAAA=CCCC Lokaler Wert gesetzt in Batch2"
Set "BBBB=!!!!!!! Lokaler Wert gesetzt in Batch2"
Werte innerhalb von Batch2:
AAAA=!!!!!!! Neuer Wert gesetzt in Batch2
BBBB=!!!!!!! Lokaler Wert gesetzt in Batch2
---wieder in Batch1.bat---- Variablen jetzt:
AAAA=AAAA LOCAL gesetzt in Batch 1
BBBB=BBBB LOCAL gesetzt in Batch 1
> Erwähnenswert: Die Variablen AAAA und BBBB sind in Batch2 zwar bekannt,
aber Batch2 kann diese nicht so mit neuen Werten füllen, dass es für Batch1 gilt.
Wenn ich aber die auskommentierte Zeile ":: Endlocal &..." entkommentiere, geht das.
Ergebnis dann:
$cmd$batch1
---in Batch1.bat ---gesetzte Variablen:
AAAA=AAAA LOCAL gesetzt in Batch 1
BBBB=BBBB LOCAL gesetzt in Batch 1
---in Batch1.bat --- Rufe "Batch2.bat AAAA"
In Batch2... überprüfe gesetzte Variablen "AAAA"/"BBBB"
Selbst noch nichts gesetzt...
AAAA=AAAA LOCAL gesetzt in Batch 1
BBBB=BBBB LOCAL gesetzt in Batch 1
Set "AAAA=CCCC Lokaler Wert gesetzt in Batch2"
Set "BBBB=!!!!!!! Lokaler Wert gesetzt in Batch2"
Werte innerhalb von Batch2:
AAAA=!!!!!!! Neuer Wert gesetzt in Batch2
BBBB=!!!!!!! Lokaler Wert gesetzt in Batch2
---wieder in Batch1.bat---- Variablen jetzt:
AAAA=!!! Auch Neu
BBBB=!!!!!!! Lokaler Wert gesetzt in Batch2
Beide Syntax-Varianten habe ich auch in Produktiv-Bätchen im Einsatz.
Wem es jetzt einleuchtet, dass auch eine Anweisung wie 'Set "BBBB=%BBBB%"' Sinn machen kann, der hat es verstanden.
Lasst Euch also NICHT solche Anweisungen von übereifrigen Praktikanten wieder rauslöschen.
Ebenfalls elegant bei mehreren "global bekanntzumachenden Variablen" ist die Zeile:
Endlocal & for %%i in ("var1=%var1%" "var2=%var2%" ..) do set %%i
Alles klar? *gg
Schönes Wochenende
Biber
tja,
man lernt nie aus das ist ja das schöne an der IT
Ich bin immer davon ausgegangen, das Änderungen an Variablen nicht an die Parentshell zurückgegeben werden.
Jetzt verstehe ich auch den Sinn von setlocal ))
Wobei ich es möglichst vermeide 2 Batches zu verwenden, seitdem ich gelernt habe, dass es auch bei batches Prozeduren gibt.
Grüße
Dieter
man lernt nie aus das ist ja das schöne an der IT
Ich bin immer davon ausgegangen, das Änderungen an Variablen nicht an die Parentshell zurückgegeben werden.
Jetzt verstehe ich auch den Sinn von setlocal ))
Wobei ich es möglichst vermeide 2 Batches zu verwenden, seitdem ich gelernt habe, dass es auch bei batches Prozeduren gibt.
Grüße
Dieter
@djbrandt
...oder, wie ich es formulieren würde: Es ist schon schwierig genug, einen Batch zum Fliegen zu bringen...
Ich jedenfalls habe meist schon Schwierigkeiten bei mittelkomplexen Onelinern...
...und zwei miteinander globale Variable austauschende Bätche überlasse ich lieber den Profis.. *gg
Schönen Abend
Biber
Wobei ich es möglichst vermeide 2 Batches zu verwenden, seitdem ich gelernt habe, dass es auch bei batches Prozeduren gibt.
Ich jedenfalls habe meist schon Schwierigkeiten bei mittelkomplexen Onelinern...
...und zwei miteinander globale Variable austauschende Bätche überlasse ich lieber den Profis.. *gg
Schönen Abend
Biber