Was ist der einfachste Weg, um ERRORLEVEL auf Null zurückzusetzen?

75

Ich habe ein Post-Build-Ereignis, das einige Befehle für ein ac # -Projekt ausführt. Der letzte Befehl führte manchmal dazu, dass der ERRORLEVEL-Wert nicht gleich Null war und der Build dann fehlschlug.

Ich möchte eine zusätzliche Befehlszeile anhängen, um den ERRORLEVEL-Wert immer auf Null zu setzen. Was ist der bequemste Weg, das zu tun?

user95319
quelle
Der Build schlägt nicht wirklich fehl, nur die IDE sieht so aus.
Dykam
10
Mir ist klar, dass dies ein ziemlich alter Beitrag ist ... Ich hatte Erfolg beim Zurücksetzen der Fehlerstufe auf 0, indem ich nach dem letzten Befehl den Befehl "type nul" ausgab. Ich hatte nur das Gefühl, dass es von Nutzen sein könnte.
Arun

Antworten:

70

Wenn Sie verwenden exit /b 0, können Sie ein errorlevel 0Skript aus einem untergeordneten Stapel zurückgeben, ohne auch das übergeordnete Skript zu verlassen.

akf
quelle
5
Von allen vorgeschlagenen Lösungen ist dies wahrscheinlich die beste. Ich werde diese Zeile in ein resetErrorlevel.bat- Skript werfen . Alles in allem ist die Tatsache, dass man sich so viel Mühe geben muss, um etwas so Triviales wie das Löschen der Fehlerstufe eines Skripts zu tun, ein weiterer Beweis dafür, dass der Erfinder der Windows-Batch-Programmierung aufgespürt und hart bestraft werden sollte. ;)
antred
53

Scheint den Trick zu machen:

ver > nul

Nicht alles funktioniert und es ist nicht klar warum. Zum Beispiel die folgenden nicht:

echo. > nul
cls > nul
Jason Kresowaty
quelle
12
Ich denke, der Grund, warum "echo" und "cls" nicht funktionieren, ist, dass es sich um in die Shell integrierte Befehle handelt, nicht um echte Programme.
user95319
2
Ich gebe dir das, aber wo ist ver.exe?
Jason Kresowaty
1
In der Batch-Befehlszeile gibt "ver" die MS Windows-Version zurück, z. B. "Microsoft Windows [Version 6.1.7601]".
AnneTheAgile
5
Wenn Sie die Hilfe in der Befehlsshell ausführen, werden Sie sehen, dass ver auch ein eingebauter Befehl ist
Baiyan Huang
2
@BaiyanHuang - Ich bin fast sicher, dass "ver"es sich um einen internen Befehl handelt, aber wie können Sie das beurteilen "help"? Viele der aufgeführten Befehle in "help"sind "externe" Befehle wie: Find.exe, Findstr.exe, Help.exe, Subst.exe, Wmic.exe, Xcopy.exe, ...
Kevin Fegan
32

Wenn in einem Pre- oder Post-Build-Ereignis der Rückkehrcode einer ausführbaren Datei größer als Null ist und der Aufruf der ausführbaren Datei nicht die letzte Zeile des Pre- oder Post-Build-Ereignisses ist, können Sie ihn schnell stummschalten und vermeiden Wenn Sie eine Prüfung auf eine Nicht-Null auslösen errorlevel, folgen Sie der fehlerhaften Zeile eine Zeile, die explizit Null zurückgibt:

cmd /c "exit /b 0"

Dies ist im Wesentlichen eine generische Kombination der zuvor genannten Lösungen, die mit mehr als nur der letzten Zeile eines Ereignisses vor oder nach dem Build funktionieren .

Jeffrey Wilges
quelle
Danke, das hat bei mir funktioniert. Der leichter klingende Vorschlag von 'Exit 0' oben schneidet nicht ab, da ich nach dem Zurücksetzen der Fehlerstufe weiterarbeiten möchte, nicht Exit
Madoki
4
Noch ausgefallener: Sie können <some failing command> || cmd /c "exit /b 0"als Einzeiler verwenden.
Alyssa Haroldsen
Ich mag diese Methode zum Festlegen einer beliebigen Fehlerstufe wie : cmd /c "exit /b 9009", aber es scheint ein bisschen übertrieben, sie auf 0 zu setzen. Würde ver > nul(ein interner Befehl) nicht genauso gut mit weniger Aufwand funktionieren als das Laden einer weiteren Kopie der Befehlsshell mit cmd /c "exit /b 0"?
Kevin Fegan
2
Das /bwird nicht benötigt, cmd /c “exit 0”funktioniert also auch gut.
Ross Smith II
Ich mag, dass dieser den Job macht. Vielen Dank. Eine lustige Sache beim Verfolgen einer Datei und meine Fehlerstufe änderte sich ständig auf 1, schließlich stellte ich fest, dass das Auffordern des Benutzers wie (set / p id = "enter id") die Fehlerstufe auf 1 ändert! ... Ich hatte das b
A Khudairy
17

Ich fand, dass "exit 0" ein guter Weg ist, um dieses Problem zu lösen.

Anwendungsbeispiel:

NET STOP UnderDevService / Y.

Ausfahrt 0

wenn der UnderDevService-Dienst nicht gestartet wird.

user95319
quelle
9
Nicht, wenn Sie diese Batchdatei auch über die Befehlszeile ausführen möchten, da Exit 0 das Fenster schließt. cmd / c "exit / b 0" wie unten vorgeschlagen ist viel besser
madoki
15

Ich persönlich benutze dies:

cd .

Funktioniert auch in Unix-Shell.

Aber dieser könnte etwas schneller sein:

type nul>nul

Da Process Monitorzeigt QueryDirectoryAnrufe ancd .

PS: cd . hat einen weiteren schönen Nebeneffekt in der Unix-Shell. Das neu erstellte Arbeitsverzeichnis im Terminal wird wiederhergestellt, wenn es vor dem Löschen geöffnet wurde.

Andry
quelle
9

Ich benutze VERIFYoderVERIFY > nul

ixe013
quelle
7

Wenn dies ein Ausschnitt wie "Post-Build-Ereignis" usw. ist, können Sie Folgendes anhängen:

(...) || ver > nul

am Ende des letzten Befehls.

Alternative

cmd /c "exit /b 0"

ist sehr sauber und nicht idiomatisch - ein Leser, der die Windows-Shell kennt, weiß, was los ist und was Ihre Absicht war.

Wenn Sie sich jedoch in einem Batch-Skript befinden, möchten Sie möglicherweise Subrotinen verwenden, die dem "untergeordneten Batch-Skript" aus der Antwort von akf entsprechen.

Haben Sie eine Unterroutine:

:reset_error
exit /b 0

und dann einfach

call :reset_error

wo immer Sie es brauchen.

Hier ist ein vollständiges Beispiel:

@echo off
rem *** main ***

call :raise_error
echo After :raise_error ERRORLEVEL = %ERRORLEVEL%

call :empty
echo After :empty ERRORLEVEL = %ERRORLEVEL%

call :reset_error
echo After :reset_error ERRORLEVEL = %ERRORLEVEL%

:: this is needed at the end of the main body of the script
goto:eof

rem *** subroutines ***

:empty
goto:eof

:raise_error
exit /b 1

:reset_error
exit /b 0

Welche Ausgänge:

After :raise_error ERRORLEVEL = 1
After :empty ERRORLEVEL = 1
After :reset_error ERRORLEVEL = 0

Wie Sie sehen - nur anrufen und über goto: eof zurückkehren ist nicht genug.

Tomasz Gandor
quelle
2

Hier sind einige andere Möglichkeiten zum Zurücksetzen des ErrorLevelStatus, die sogar unter MS-DOS funktionieren (zumindest für Version 6.22):

more < nul > nul

rem // The `> nul` part can be omitted in Windows but is needed in MS-DOS to avoid a line-break to be returned:
sort < nul > nul

Die folgenden Methoden funktionieren nur unter MS-DOS:

command /? > nul

fc nul nul > nul

keyb > nul

Der Vollständigkeit halber setzt dies den ErrorLevelStatus auf 1, der sowohl für Windows als auch für MS-DOS gültig ist:

< nul find ""
aschipfl
quelle
0

>nulNach jedem Befehl hinzufügen , der wahrscheinlich fehlschlägt - dies scheint zu verhindern, dass der Build fehlschlägt.

Sie können das Ergebnis des Befehls weiterhin überprüfen, indem Sie es untersuchen %errorlevel%.

Zum Beispiel:

findstr "foo" c:\temp.txt>nul & if %errorlevel% EQU 0 (echo found it) else (echo didn't find it)
Chiefy
quelle
2
Dies funktioniert nicht - die Shell wertet die gesamte Befehlszeile auf einmal aus, sodass% errorlevel% ersetzt wird, bevor der Befehl "findstr" ausgeführt wird. Verwenden Sie stattdessen "if errorlevel 1", um auf einen Fehlerlevel ungleich Null zu testen.
UweBaemayr
2
Wahrscheinlich schlägt Ihr CI-Server fehl, wenn er beispielsweise die Zeichenfolge "error" in der Standardausgabe / dem Standardfehler findet. Sie setzen den Status nicht zurück. Sie bringen den Befehl nur zum Schweigen. Für eine tiefere Stille verwenden Sie> nul 2> nul
Tomasz Gandor
0

Nachdem ich alle anderen Antworten überprüft hatte, entschied ich mich herauszufinden, welcher Weg am effizientesten zum Zurücksetzen des FEHLERS war. Ich habe ein schnelles Skript erstellt, das die Zeit für die Ausführung der folgenden Aufgaben aufzeichnet:

"cmd /c "exit /b 0"", "cd .", "ver", "type nul", and "VERIFY"

Hier ist die Ausgabe:

cmd / v: on / c set ^ "q = ^" ^ "& timeit.cmd" cmd / c ^! q ^! exit / b 0 ^! q ^! "" cd. "" ver "" type nul " "ÜBERPRÜFEN"

cmd / c "exit / b 0" dauerte 0: 0: 0,02 (insgesamt 0,02 s)

cd. nahm 0: 0: 0,00 (0,00s insgesamt)

Microsoft Windows [Version 10.0.18362.836]

ver nahm 0: 0: 0,00 (0,00s insgesamt)

Typ nul nahm 0: 0: 0,00 (0,00s insgesamt)

VERIFY ist ausgeschaltet. VERIFY dauerte 0: 0: 0,00 (insgesamt 0,00 s)


Dies dauerte 0: 0: 0,06 (insgesamt 0,06 s)

Nachdem Measure-Command {command}ich mit in Powershell nachgesehen hatte , stellte ich fest, dass es nur wirklich akzeptiert wurde cd .und - cmd /c "exit /b 0"mache ich etwas falsch?

Ich würde empfehlen, entweder cd .oder type nulda weder einen Fußabdruck auf der Ausgabe der Konsole haben, noch sind sie in irgendeiner Weise langsam.

Ja, mir ist ziemlich langweilig

alexlyee
quelle
Ja, cmd /C exit [/B] 0sollte die langsamste sein, seit eine neue cmd.exeInstanz geöffnet und geschlossen wird. Die anderen sind alle interne Befehle, daher gibt es keinen Dateisystemzugriff, um ausführbare Dateien zu finden…
aschipfl
0

Folgendes funktioniert in modernen Windows-Systemen (NT-basierten Systemen) mit folgenden Funktionen cmd.exe:

rem /* This clears `ErrorLevel`; the SPACE can actually be replaced by an
rem    arbitrary sequence of SPACE, TAB, `,`, `;`, `=`, NBSP, VTAB, FF: */
(call )

Der SPACE(oder genauer gesagt, eine beliebige Folge von einem oder mehreren Standard - Token - Separatoren, die sind SPACE(Code 0x20), TAB(Code 0x09), ,, ;, =, NBSP(Code 0xFF), VTAB(Code 0x0B) und FF(Code 0x0C)) obligatorisch; Wenn Sie es weglassen, ErrorLevelwird stattdessen Folgendes festgelegt:

rem // This sets `ErrorLevel` to `1`:
(call)

Es gibt einen schönen Thread auf DosTips.com, in dem diese Technik aufgetaucht ist.


Hier ist eine alternative Methode, die jedoch auf das Dateisystem zugreift und daher möglicherweise etwas langsamer ist:

dir > nul

rem /* Perhaps this is a little faster as a specific file is given rather 
rem    than just the current directory (`.` implicitly) like above: */
dir /B "%ComSpec%" > nul
aschipfl
quelle
-2

Ich benutze dies:

ping localhost -n 1> null

Piotr Domanski
quelle
-5

Ich habe immer nur benutzt;

set ERRORLEVEL=0

Ich benutze es seit Eselsjahren.

Cirrus
quelle
29
Es ist einfach, aber es ist eine wirklich schlechte Idee, da dadurch eine Variable mit dem Namen erstellt wird, errorleveldie die interne errorlevel
Pseudovariable
6
Crikey, du hast recht! Wow, es sieht so aus, als ob ich seit Jahren Kugeln ausweiche :)
Cirrus