Findstr in for schleife gibt kein errorlevel zurück
Hallo,
Ich möchte innerhalb einer for schleife den findstr Befehl nutzen. Ich habe hier das Problem das findstr immer %errorlevel%= 0 ausgibt, egal ob der gesuchte string in text2.txt vorkommt oder nicht.
Kann mir jemand weiterhefen ?
Ich möchte innerhalb einer for schleife den findstr Befehl nutzen. Ich habe hier das Problem das findstr immer %errorlevel%= 0 ausgibt, egal ob der gesuchte string in text2.txt vorkommt oder nicht.
@echo on & enabledelayedexpansion
for /f "tokens=1,2,3,4 delims= " %%i in ('findstr "name" text1.txt') do (
findstr "%%j" text2.txt
if %errorlevel% EQU 0 echo %%i %%j %%k %%l>>text2.txt
)
Kann mir jemand weiterhefen ?
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 134937
Url: https://administrator.de/contentid/134937
Ausgedruckt am: 22.11.2024 um 19:11 Uhr
17 Kommentare
Neuester Kommentar
Moin didie08,
ersetze das "if %errorlevel% EQU 0 echo " innerhalb der FOR-Anweisung durch ein "if NOT ERRORLEVEL 1 echo "
Erläuterung:
wenn du innerhalb einer Befehlszeile (und auch eine mehrzeilig formatierte FOR-Anweisung ist eine Befehlszeile) eine %variable% ansprichst,
so wie du in deinem Beispiel %errorlevel%, dann wird si einmal aufgelöst (quasi zu Beginn der Ausführung) und nicht dynamisch.
Grüße
Biber
ersetze das "if %errorlevel% EQU 0 echo " innerhalb der FOR-Anweisung durch ein "if NOT ERRORLEVEL 1 echo "
Erläuterung:
wenn du innerhalb einer Befehlszeile (und auch eine mehrzeilig formatierte FOR-Anweisung ist eine Befehlszeile) eine %variable% ansprichst,
so wie du in deinem Beispiel %errorlevel%, dann wird si einmal aufgelöst (quasi zu Beginn der Ausführung) und nicht dynamisch.
Grüße
Biber
(nur falls das jemand mal per google findet) - die Lösung ist richtig, aber die Erklärung trifft's nicht.
Wenn Du %errorlevel% benutzt, dann wird damit eine Umgebungsvariable namens errorlevel gemeint. Die gibt es in der Regel aber nicht!
Was Du wirklich meinst, ist der Rückgabewert ERRORLEVEL. Der wird wie in der Lösung per "IF ERRORLEVEL wert" abgefragt.
Noch fataler wird es, wenn man vorsichtshalber vor dem überwachten Befehl den ERRORLEVEL zurücksetzen will:
(FALSCH)
set /a %errorlevel%=0
Befehl
if %errorlevel% EQU 0 ....wird immer ausgeführt!
(RICHTIG)
verify >nul
if not errorlevel 1 ...
Noch eine Falle:
Bei IF ERRORLEVEL wird auf "grösser gleich wert" geprüft, nicht auf Gleichheit. Daher die Negation: "NOT >=" bedeutet "<". Der Grund ist, dass ein Rückgabewert von 0 OK bedeutet, alles andere FEHLER. Welcher Fehler kann dann aus dem Wert bestimmt werden (interessiert hier aber nicht).
HTH
Ede
Wenn Du %errorlevel% benutzt, dann wird damit eine Umgebungsvariable namens errorlevel gemeint. Die gibt es in der Regel aber nicht!
Was Du wirklich meinst, ist der Rückgabewert ERRORLEVEL. Der wird wie in der Lösung per "IF ERRORLEVEL wert" abgefragt.
Noch fataler wird es, wenn man vorsichtshalber vor dem überwachten Befehl den ERRORLEVEL zurücksetzen will:
(FALSCH)
set /a %errorlevel%=0
Befehl
if %errorlevel% EQU 0 ....wird immer ausgeführt!
(RICHTIG)
verify >nul
if not errorlevel 1 ...
Noch eine Falle:
Bei IF ERRORLEVEL wird auf "grösser gleich wert" geprüft, nicht auf Gleichheit. Daher die Negation: "NOT >=" bedeutet "<". Der Grund ist, dass ein Rückgabewert von 0 OK bedeutet, alles andere FEHLER. Welcher Fehler kann dann aus dem Wert bestimmt werden (interessiert hier aber nicht).
HTH
Ede
Moin edepfau,
nur falls jemand das über eine Suchmaschine findet:
Diesen Satz.
Wenn du einfach z.B. die Hilfe zu SET (oder anderen) aufrufst und nach "errorlevel" suchst, liest Du [in Zeile 03], was ich meine:
%errorlevel% als dynamische Variable gibt es IMMER und (deswegen ja dynamisch) IMMER nach jeder abgesetzten Befehlszeile aktualisiert/expandiert.
So wie auch %date%, %time%, %random%. Diese Variablen werden allesamt nicht bei SET angezeigt, aber "es gibt sie schon".
Besonderheit bei der Prüfung des ERRORLEVELs ist aber unter anderem, dass es neben der üblichen Syntax "IF %errorlevel% == n" auch noch die Syntax "IF ERRORLEVEL n" gibt... ohne Prozentzeichen drumherum und ohne Gleichheitszeichen. Und dieses "IF ERRORLEVEL n" wird eben nicht wie ein "IF %errorlevel% ==.." bei Beginn der Ausführung aufgelöst.
Grüße
Biber
nur falls jemand das über eine Suchmaschine findet:
Diesen Satz.
...wird damit eine Umgebungsvariable namens errorlevel gemeint. Die gibt es in der Regel aber nicht!
möcte ich ungern so stehen lassen.Wenn du einfach z.B. die Hilfe zu SET (oder anderen) aufrufst und nach "errorlevel" suchst, liest Du [in Zeile 03], was ich meine:
>set /?|find /i "errorlev"
Der SET-Befehl legt den ERRORLEVEL mit 1 fest, wenn der Variablenname nicht
%ERRORLEVEL% - expandiert zum aktuellen ERRORLEVEL-Wert.
%errorlevel% als dynamische Variable gibt es IMMER und (deswegen ja dynamisch) IMMER nach jeder abgesetzten Befehlszeile aktualisiert/expandiert.
So wie auch %date%, %time%, %random%. Diese Variablen werden allesamt nicht bei SET angezeigt, aber "es gibt sie schon".
Besonderheit bei der Prüfung des ERRORLEVELs ist aber unter anderem, dass es neben der üblichen Syntax "IF %errorlevel% == n" auch noch die Syntax "IF ERRORLEVEL n" gibt... ohne Prozentzeichen drumherum und ohne Gleichheitszeichen. Und dieses "IF ERRORLEVEL n" wird eben nicht wie ein "IF %errorlevel% ==.." bei Beginn der Ausführung aufgelöst.
Grüße
Biber
Das stimmt so nicht, und weil diese Meinung so weit verbreitet ist, habe ich auf den Unterschied hingewiesen.
Die errorlevel Variable ist eben keine Umgebungsvariable, d.h. wird nicht im Environment definiert, abgefragt oder gelöscht. MS hat die Syntax der der Umgebungsvariablen angepasst, um dem User nicht noch eine Schreibweise zuzumuten (z.B. $errorlevel$). Und weil das keine Umgebungsvariable ist, braucht man auch keine delayed expansion (den Befehl kann man oben gleich löschen).
Wenn man den Unterschied kennt, dann wird man auch nicht versucht sein,
set /a ERRORLEVEL 3
zu tippen. Das klappt zwar, aber dann hat man eine Umgebungsvariable gleichen Namens erzeugt, die völlig statisch ist. D.h. man kann den Rückgabewert von Befehlen nicht mehr (mit %errorlevel%) abfragen.
Hier ist ein Artikel, der das beschreibt (aus MSDN): The Old New Thing - ERRORLEVEL is not %ERRORLEVEL%
in http://blogs.msdn.com/oldnewthing/archive/2008/09/26/8965755.aspx
Gruß,
Ede
Die errorlevel Variable ist eben keine Umgebungsvariable, d.h. wird nicht im Environment definiert, abgefragt oder gelöscht. MS hat die Syntax der der Umgebungsvariablen angepasst, um dem User nicht noch eine Schreibweise zuzumuten (z.B. $errorlevel$). Und weil das keine Umgebungsvariable ist, braucht man auch keine delayed expansion (den Befehl kann man oben gleich löschen).
Wenn man den Unterschied kennt, dann wird man auch nicht versucht sein,
set /a ERRORLEVEL 3
zu tippen. Das klappt zwar, aber dann hat man eine Umgebungsvariable gleichen Namens erzeugt, die völlig statisch ist. D.h. man kann den Rückgabewert von Befehlen nicht mehr (mit %errorlevel%) abfragen.
Hier ist ein Artikel, der das beschreibt (aus MSDN): The Old New Thing - ERRORLEVEL is not %ERRORLEVEL%
in http://blogs.msdn.com/oldnewthing/archive/2008/09/26/8965755.aspx
Gruß,
Ede
Moin edepfau,
ich denke, da hast du etwas missverstanden.
Aber ist mir auch nicht so wichtig und ich denke, die MitleserInnen können sich in dem angeführten Blog-Artikel und in der Hilfe am CMD-Prompt ja selbst ein Bild.
machen.
Dieses absurde Beispiel mit dem "SET ERRORLEVEL=whatever"... ja hey! Das ist Dönekens.
Du kannst beispielsweise auch die dynamische %random%-Variable auf 42 setzen.
Und den Wert 42 behält sie auch..
... toller Plan...
Aber sobald du deine "lokale Privat-Übersteuerung" der im CMD.exe-Environment immer vorhandenen %random%-Variablen wegknallst...
... und die "Überlagerung" weg ist, dann siehst du wieder den eigentlichen Zustand.
Aber, wie geschrieben, es ist mir auch nicht so wichtig.
Selbst mit falscher Herleitung würde ja mein Workaround dem didie08 bei seinem begrenzten Problem nicht schaden.
Grüße
Biber
ich denke, da hast du etwas missverstanden.
Aber ist mir auch nicht so wichtig und ich denke, die MitleserInnen können sich in dem angeführten Blog-Artikel und in der Hilfe am CMD-Prompt ja selbst ein Bild.
machen.
Dieses absurde Beispiel mit dem "SET ERRORLEVEL=whatever"... ja hey! Das ist Dönekens.
Du kannst beispielsweise auch die dynamische %random%-Variable auf 42 setzen.
Und den Wert 42 behält sie auch..
>set random=42
>echo %random%
42
>echo %random%
42
Aber sobald du deine "lokale Privat-Übersteuerung" der im CMD.exe-Environment immer vorhandenen %random%-Variablen wegknallst...
>set random=
>echo %random%
24795 '-- bzw. irgendein anderer Zufallswert >=0 <=32000irgendwas
Aber, wie geschrieben, es ist mir auch nicht so wichtig.
Selbst mit falscher Herleitung würde ja mein Workaround dem didie08 bei seinem begrenzten Problem nicht schaden.
Grüße
Biber
Hallo (auch an alle, die nicht von Google hierher geführt wurden )!
Nur als Ergänzung:
Das Beispiel bekommt die größte Aussagekraft, wenn es kein Laufwerk B: gibt.
[Edit] Letzte Variante benötigt umgekehrte Schreibweise - siehe unten ... [/Edit]
Grüße
bastla
Nur als Ergänzung:
@echo off & setlocal enabledelayedexpansion
echo So nicht:
for %%i in (B: C:) do (
dir %%i >nul 2>&1
if %errorlevel% neq 0 (echo Fehler) else (echo OK)
)
echo\
echo ... aber so
for %%i in (B: C:) do (
dir %%i >nul 2>&1
if !errorlevel! neq 0 (echo Fehler) else (echo OK)
)
echo\
echo ... oder so
for %%i in (B: C:) do (
dir %%i >nul 2>&1
if errorlevel 1 (echo Fehler) else (echo OK)
)
echo\
echo ... oder auch so
for %%i in (B: C:) do (
dir %%i >nul 2>&1 || (echo Fehler) && (echo OK)
)
[Edit] Letzte Variante benötigt umgekehrte Schreibweise - siehe unten ... [/Edit]
Grüße
bastla
Moin bastla,
na, wenn denn so viele Such-MaschinistInnen hier erwartet werden, dann sollten wir denen ja was bieten.
Dann noch eine kleine Fussnote.
Wenn ich deinen Lehrschnipsel so hin drehe, dass auch die Interessierten mit vorhandenem B:-Laufwerk was zum Staunen haben und zum Testen das Laufwerk @:\ abprüfe:
dann ist die Ausgabe wie folgt:
> Bitte auf die letzten beiden Ausgabezeilen achten!!
aber fällt leider in die Kategorie works as designed...
Das macht er nur, WENN ein Fehler aufftrat... und dann macht er ZUSÄTZLICH die Anweisung rechts des "&&".
Grüße
Biber
na, wenn denn so viele Such-MaschinistInnen hier erwartet werden, dann sollten wir denen ja was bieten.
Dann noch eine kleine Fussnote.
Wenn ich deinen Lehrschnipsel so hin drehe, dass auch die Interessierten mit vorhandenem B:-Laufwerk was zum Staunen haben und zum Testen das Laufwerk @:\ abprüfe:
:: -- bastlasEL.cmd Demoschnipsel für Errorlevel-Abfrage
@echo off & setlocal enabledelayedexpansion
:: --- geprüft werden immer die Laufwerke @:\ [nicht da] und C: ["immer" da]
echo So nicht:
for %%i in (@: C:) do (
dir %%i >nul 2>&1
if %errorlevel% neq 0 (echo %%i Fehler) else (echo %%i OK)
)
echo\
echo ... aber so
for %%i in (@: C:) do (
dir %%i >nul 2>&1
if !errorlevel! neq 0 (echo %%i Fehler) else (echo %%i OK)
)
echo\
echo ... oder so
for %%i in (@: C:) do (
dir %%i >nul 2>&1
if errorlevel 1 (echo %%i Fehler) else (echo %%i OK)
)
echo\
echo ... oder auch so
for %%i in (@: C:) do (
dir %%i >nul 2>&1 || (echo %%i Fehler) && (echo %%i OK)
)
dann ist die Ausgabe wie folgt:
>BastlasEL.bat
So nicht:
@: OK
C: OK
... aber so
@: Fehler
C: OK
... oder so
@: Fehler
C: OK
... oder auch so
@: Fehler
@: OK
Grüße
Biber
@Biber
Na dann machen wir's doch so (und ich wollte es ohnehin schon vorhin umdrehen *grummel*):
Dann wird ein schönes "If - Then - Else" mit folgendem Ergebnis
draus ...
BTW: Wo ist denn vorhin das "C:" geblieben?
Grüße
bastla
Na dann machen wir's doch so (und ich wollte es ohnehin schon vorhin umdrehen *grummel*):
echo ... oder doch so
for %%i in (@: C:) do (
dir %%i >nul 2>&1 && (echo %%i OK) || (echo %%i Fehler)
)
... oder doch so
@: Fehler
C: OK
BTW: Wo ist denn vorhin das "C:" geblieben?
@: Fehler
@: OK
bastla
Moin bastla,
Na, probier doch den von mir geposteten Schnipsel mal ... das ist wirklich die Original-Demo-Ausgabe.
Interpretation:
In Summe
In Summe
Grüße
Biber
@: Fehler
@: OK
Interpretation:
@: Fehler
@: OK
In Summe
{ Näherungswert für FDP-Wirtschaftskompetenz }
Biber
@Biber
OK, Nachmittagstief vorbei - ist klar ...
Aber die umgekehrte Variante
tut bei mir tatsächlich, was sie soll.
Grüße
bastla
OK, Nachmittagstief vorbei - ist klar ...
das ist wirklich die Original-Demo-Ausgabe.
hätte ich auch nie nicht angezweifelt ...Aber die umgekehrte Variante
dir %%i >nul 2>&1 && (echo %%i OK) || (echo %%i Fehler)
Grüße
bastla
Moin bastla,
Tja, wenn die Montage manchmal etwas länger dauern... kenn ich.
Na ja sagen wir lieber... works as designed...
Wenn du das Konstrukt so formulierst...
[edit]
BullShit.... Theorie wurde schnell widerlegt... siehe unten.
[/edit]
Da diese Wahrscheinlichkeit doch eher zu vernachlässigen ist... hmm...
Ich würde es (wegen der Lesbarkeit) gleich ganz weg lassen.
Grüße
Biber
P.S. Jezz' haben die GooglerInnen aber wirklich was zu lesen....
Tja, wenn die Montage manchmal etwas länger dauern... kenn ich.
Aber die umgekehrte Variante ... tut bei mir tatsächlich, was sie soll.
Na ja sagen wir lieber... works as designed...
Wenn du das Konstrukt so formulierst...
dir %%i >nul 2>&1 && (echo %%i OK) || (echo %%i Fehler)
BullShit.... Theorie wurde schnell widerlegt... siehe unten.
[/edit]
Da diese Wahrscheinlichkeit doch eher zu vernachlässigen ist... hmm...
Grüße
Biber
P.S. Jezz' haben die GooglerInnen aber wirklich was zu lesen....
Ach so, hatte mich schon über den Krach vorhin gewundert ...
Aber ernsthaft: Welche andere Erklärung hättest Du noch für die (ebenfalls originale) Ausgabe
Grüße
bastla
Aber ernsthaft: Welche andere Erklärung hättest Du noch für die (ebenfalls originale) Ausgabe
... oder doch so
@: Fehler
C: OK
bastla