bluemen
Goto Top

ERRORLEVEL ändert sich erst bei zweitem Durchlauf

Hallo Leute,

wenn ich folgenden Code in einer Batch-Datei speichere, und diese dann ausführe, kommt es zu einem seltsamen Verhalten.

Zur "Sicherheit" zuerst den ersten Code, als Script 2x aufgerufen. Jeweils ERRORLEVEL 0.
Danach den zweiten Code, ebenfalls zweimal.

Nun das Unklare:
Beim zweiten Code bekomme ich beim ersten "Durchlauf", ebenfalls den ERRORLEVEL 0 (obwohl find nicht 0 zurückliefern sollte), beim zweiten Mal dann ERRORLEVEL 1.
Woran liegt das und wie kann ich das verhindern?
Wenn nun wieder der erste Code aufgerufen wird, erzeugt der erste Durchlauf wiederrum ERRORLEVEL 1, beim zweiten Mal dann 0.

Ich verstehe es nicht und hoffe, jemand hat einen Tipp für mich.

REM erstes Script

for /l %%i in (1,1,1) do (
echo a|find /i "a">nul  
        if %errorlevel% EQU 0 ( echo Test:Geht! Errorlevel:%errorlevel%) else (echo Test:Geht nicht! Errorlevel:%errorlevel%)
)



REM zweites Script

for /l %%i in (1,1,1) do (
echo a|find /i "ab">nul  
 	if %errorlevel% EQU 0 ( echo Test:Geht! Errorlevel:%errorlevel%) else (echo Test:Geht nicht! Errorlevel:%errorlevel%)
)

Content-ID: 665551

Url: https://administrator.de/contentid/665551

Ausgedruckt am: 22.11.2024 um 03:11 Uhr

mayho33
mayho33 08.04.2021 aktualisiert um 21:45:34 Uhr
Goto Top
Hi!

Ich bin kein Batch-Guru, aber wenn mich nicht alles täuscht, dann durchläuft deine For den String zeichenweise.

Da das erste Zeichen String ein A ist und du nach einem A suchst, das zweite Zeichen aber ein B, bekommst du beim 2. Durchlauf einen Error.


Wenn es nicht Batch sein muss, dann empfehle ich auf Powershell umzusteigen. Mit Regex oder auch der Contains-Methode oder -match läuft das wesentlich komfortabler.

If("dbfhaa".Contains("a")) {...}  

If("dbfhaa" -match "a") {...}  

If([regex]::Match("dbfhaa", "a").Success) {...}  

Grüße!
TK1987
Lösung TK1987 08.04.2021 aktualisiert um 22:11:00 Uhr
Goto Top
Moin,

Variablen, die sich innerhalb einer Befehlsgruppierung (in deinem Fall die For-Schleife) ändern; und innerhalb der selben Gruppierung wieder aufgerufen werden, müssen verzögert werden. Andernfalls wird der Wert ausgegeben, den die Variable vor der Gruppierung hatte.
@echo off
SetLocal EnableDelayedExpansion

for /l %%i in (1,1,1) do (
echo a|find /i "ab">nul  
 	if !errorlevel! EQU 0 ( echo Test:Geht^^! Errorlevel:!errorlevel!) else (echo Test:Geht nicht^^! Errorlevel:!errorlevel!)
)

Gruß Thomas
bluemen
bluemen 09.04.2021 aktualisiert um 08:50:11 Uhr
Goto Top
Guten Morgen und

vielen Dank Thomas, das war die Lösung!

Ich habe noch eine Frage zu den Ausrufezeichen. Wann müssen die gesetzt werden? Wenn ich es richtig verstehe, wird der Interpreter dadurch veranlasst, die Variable erst "bei Bedarf" auszulesen. Bedeutet das, ich ersetze % durch !, wenn die Variable verzögert ausgelesen werden soll und bei allen anderen (nicht verzögert auszulesenden) bleibt es bei % (wie z.B. in der Schleife (%%i)?
Und was machen die ^^? Wofür sie sorgen habe ich herausgefunden, nur bislang keine Erklärung im Netz gefunden, um die generelle Verwendung zu verstehen. Magst du das eventuell noch etwas kommentieren bzw. gibt es eine Quelle, wo man die Infos gebündelt findet?

Danke
Bodo

PS: Noch eine Frage ohne direkten Zusammenhang. Wie bekomme ich das Ergebnis in die "Wunsch"Variable --> echo %%~ni|find /i "a">%wunschvariable% hat bislang nicht funktioniert.
TK1987
Lösung TK1987 09.04.2021 aktualisiert um 08:50:00 Uhr
Goto Top
Ich habe noch eine Frage zu den Ausrufezeichen. Wann müssen die gesetzt werden?
sobald die Variablenverzögerung mit Setlocal EnableDelayedExpansion aktiviert wurde, kann man theoretisch jede Variable sowohl mit %, als auch mit ! aufrufen.

Dies wird z.B. dann erforderlich, wenn Befehle entweder in Klammern oder mit einem "&" Gruppiert wurden. Führe zum Beispiel mal folgendes Skript aus:
@echo off

set x=0
(
  set /a x+=1
  echo x=%x%
  set /a x+=1
  echo x=%x%
  set /a x+=1
  echo x=%x%
)
echo x=%x%
pause

Was macht das Skript? Erst setzen wir die Variable x auf 0. Dann in den Klammern erhöhen 3 mal um 1 und geben es aus. Anschließend hinter den Klammern geben wir x erneut aus.

Erwarten würde man hier nun:
x=1
x=2
x=3
x=3
Dieses Ergebnis würden wir ohne Klammern auch erhalten - hier erhalten wir jedoch 3x "x=0". Man könnte meinen es wurde nicht gezählt - am Ende erhalten wir hinter der Klammer jedoch vollkommen korrekt "x=3".
Die Variable x haben wir innerhalb der Gruppierung geändert. Um dort das aktuelle Ergebnis zu erhalten, muss die Variable mit ! Verzögert werden.

Und was machen die ^^?
Das sind Escapezeichen. Sobald die Variablenverzögerung aktiviert wurde, werden Ausrufezeichen als Variablen interpretiert. Um einen Text mit einem Ausrufezeichen ausgeben zu können, musst du in dem Fall die Ausrufezeichen so darstellen.
bluemen
bluemen 09.04.2021 aktualisiert um 09:10:26 Uhr
Goto Top
Super Erklärung!

Hab gerade viel gelernt ... und mir erlaubt, noch eine Frage "nachzuschieben". Wenn ich dazu noch einen Tipp bekomme, ist der Tag perfekt! face-smile

... PS: Noch eine Frage ohne direkten Zusammenhang. Wie bekomme ich das Ergebnis in die "Wunsch"Variable --> echo %%~ni|find /i "a">%wunschvariable% hat bislang nicht funktioniert.
TK1987
TK1987 09.04.2021 aktualisiert um 09:37:25 Uhr
Goto Top
Wie bekomme ich das Ergebnis in die "Wunsch"Variable --> echo %%~ni|find /i "a">%wunschvariable% hat bislang nicht funktioniert.
Deine Variable %%i ist bislang ja auch nur eine Zählervariable.
Woher soll der Wert für deine "Wunschvariable" den kommen? TXT, CSV oder woraus soll die ausgelesen werden?
Folgendes gibt dir eine Text-Datei zeilenweise aus:
for /f "usebackq" %%A in ("C:\Test\Quelle.TXT") do (  
  echo Mach was mit "%%A"  
)

gibt es eine Quelle, wo man die Infos gebündelt findet?
Glaube nicht, es gibt m.W.n. nur Befehlserläuterungen, die aber im Prinzip auch nur die Hilfedateien wiedergeben, oder Erläuterungen zu bestimmten Problemen.
CMD zu erlernen ist in der heutigen Zeit aber ohnehin auch ziemlich Sinnfrei, da die Sprache längst tot ist, nur sehr eingeschränkte Möglichkeiten bietet und zudem ziemlich buggy ist.

Heute nimmt man für sowas Powershell, ist sowieso viel leichter zu lernen und dafür gibt es auch gebündelte Infos:
bluemen
bluemen 09.04.2021 aktualisiert um 09:52:31 Uhr
Goto Top
Sorry, der notwendige "Rest" hat gefehlt.

for /R %WUNSCHPFAD% %%i in ("*.xyz") do (  
			echo %%~ni|find /i "abc">%WUNSCHVARIABLE%  
)

Das Ergebnis von find hätte ich gern an die wunschvariable übergeben.

Powershell schaue ich mir an. face-smile
TK1987
TK1987 09.04.2021 um 11:08:42 Uhr
Goto Top
Dafür nimmt man besser findstr.
@echo off
for /f "Tokens=2* Delims=:" %%A in ('findstr "abc" *.xyz') do (  
  echo %%A
)
So erhälst du in der Schleifenvariable %%A jeweils die Zeilen, die die Zeichenfolge "abc" enthalten. Mit dieser kannst du dann weiterarbeiten.
bluemen
bluemen 09.04.2021 um 11:37:50 Uhr
Goto Top
Ok, dann nutze ich diesen Weg.

Würdest du mir bitte (trotzdem) verraten, wie ich in dem Beispiel:
echo %%~ni|find /i "abc">%WUNSCHVARIABLE%  
das Ergebnis in %WUNSCHVARIABLE% bekomme?
TK1987
TK1987 09.04.2021 aktualisiert um 11:46:35 Uhr
Goto Top
@echo off
for /f "Tokens=2* Delims=:" %%A in ('findstr "abc" *.xyz') do (  
  set WUNSCHVARIABLE=%%A
)
bluemen
bluemen 09.04.2021 aktualisiert um 12:06:21 Uhr
Goto Top
Sorry, dass ich noch einmal frage aber mir ging es genau um dieses Beispiel, da ich verstehen möchte, warum > nicht funktioniert bzw. wie der korrekte Syntax lautet.
echo %%~ni|find /i "abc">%WUNSCHVARIABLE%  

Danke für deine Geduld und ein schönes Wochenende
Noch eine Frage kommt (heute) nicht! face-smile
TK1987
TK1987 09.04.2021 aktualisiert um 12:49:43 Uhr
Goto Top
">" leitet die Ausgabe eines Befehls in eine Datei um - nicht in Variablen.
Dein Beispiel funktioniert also nur, wenn in deiner Wunschvariable eine Pfadangabe steht, z.B.
set WUNSCHVARIABLE=C:\Test\Ausgabe.txt
...
echo %%~ni|find /i "abc">%WUNSCHVARIABLE%  
würde dazu führen, das die Zeile(n), die du mit find gefunden hast, in die Datei "C:\Test\Ausgabe.txt" geschrieben wird.
NikosLykos
NikosLykos 09.04.2021 um 13:58:35 Uhr
Goto Top
Hallo,

eine gute Quelle wenn es um Batch und Powershell geht ist ss64.com.

Schau dich da mal um.

Gruß
Klaus
bluemen
bluemen 13.04.2021, aktualisiert am 14.04.2021 um 16:57:23 Uhr
Goto Top
Ich habe noch eine Frage hierzu:
for /R %WUNSCHPFAD% %%i in ("*.xyz") do (  
			echo %%~ni|find /i "abc">%WUNSCHVARIABLE%  
)

Wie müsste der Code aussehen, wenn die Schleife nicht rekursiv arbeiten sollte (/R), bzw. ein bestimmtes Unterverzeichnis von der Bearbeitung ausgenommen werden soll?