将ERRORLEVEL重置为零的最简单方法是什么?


76

我有一个构建后事件,该事件为ac#项目运行一些命令。最后一条命令有时会导致ERRORLEVEL值不等于零,然后构建失败。

我想附加一条命令行,以将ERRORLEVEL值始终设置为零。最方便的方法是什么?


构建并没有真正失败,只有IDE看起来确实如此。
Dykam,2009年

10
我意识到这是一个很老的帖子...通过在最后一个命令之后发出命令“ type nul”,我成功地将错误级别重置为0。只是觉得可能有用。
阿伦(Arun)

Answers:


70

如果使用exit /b 0,则可以errorlevel 0从子批处理脚本中返回一个,而无需退出父级。


5
在所有提出的解决方案中,这可能是最好的解决方案。我将把这条线扔到resetErrorlevel.bat脚本中。总而言之,事实上,必须付出如此艰辛的努力来完成清除脚本错误级别这样的琐碎工作,这进一步证明了Windows批处理编程的发明者应该受到追捕和严惩。;)
antant

55

似乎可以解决问题:

ver > nul

并非所有方法都能正常工作,并且不清楚原因。例如,以下内容不会:

echo. > nul
cls > nul

12
我认为“ echo”和“ cls”不起作用的原因是因为它们是Shell内置命令,而不是实际程序。
user95319 2009年

2
我给你,但是ver.exe在哪里?
贾森·克雷索瓦蒂

1
在批处理命令行中,“ ver”返回MS Windows版本,例如“ Microsoft Windows [Version 6.1.7601]”。
AnneTheAgile

5
如果您在命令外壳中运行帮助,您将看到ver也是一个内置命令
baye 2014年

2
@BaiyanHuang-我几乎肯定"ver"是一个内部命令,但是您怎么知道"help"呢?许多中列出的命令"help"是“外部”的命令,如:Find.exeFindstr.exeHelp.exeSubst.exeWmic.exeXcopy.exe,...
凯文·费根

32

在构建前或构建后事件中,如果可执行文件的返回码大于零,并且对可执行文件的调用不是构建前或构建后事件的最后一行,则可以通过一种快速方法将其静音并避免触发检查是否为非零errorlevel是在失败行之后跟随显式返回零的行:

cmd /c "exit /b 0"

这实质上是前面提到的解决方案的通用组合,不仅可以用于构建前或构建后事件的最后一行。


谢谢,这对我有用。上面“退出0”的听起来更容易的建议并没有消除它,因为我希望在重置错误级别后继续做一些事情,而不是退出
madoki

4
更花哨的是:您可以将其<some failing command> || cmd /c "exit /b 0"用作一体式内胆。
Alyssa Haroldsen

我喜欢这种用于设置任意错误级别的方法,例如:cmd /c "exit /b 9009",但是将其设置为0似乎有点过头了。ver > nul(内部命令)与加载另一个带有shell的命令shell副本相比,其工作开销也更少cmd /c "exit /b 0"吗?
凯文·费根

2
/b不需要这样cmd /c “exit 0”的作品也没关系。
罗斯·史密斯二世

我喜欢这个工作。谢谢。一件有趣的事,我正在跟踪某个文件,并且我的错误级别一直更改为1,最后我发现提示用户像(set / p id =“ enter id”)会将错误级别更改为1!...我填满了b
A Khudairy,

18

我发现“出口0”看起来是解决此问题的好方法。

用法示例:

NET STOP UnderDevService / Y

出口0

如果未启动UnderDevService服务。


10
如果您还想从命令行运行该批处理文件,则不要这样做,因为出口0将关闭该窗口。如下所示,cmd / c“ exit / b 0”更具挑战性
madoki

16

我个人使用此:

cd .

即使在unix shell中也可以使用。

但是,这可能会更快一些:

type nul>nul

因为Process Monitor显示QueryDirectory通话cd .

PS: cd .在unix外壳中还有另一个不错的副作用。如果在擦除之前已经打开了工作目录,它将在终端中恢复创建的工作目录。



7

如果这是“构建后事件”之类的代码段,则可以添加以下内容:

(...) || ver > nul

在最后一条命令的末尾。

或者

cmd /c "exit /b 0"

非常干净而且没有习惯-知道Windows shell的读者会知道正在发生什么以及您的意图是什么。

但是,如果您使用的是批处理脚本,则可能要使用subrotines,它与akf答案中的“子批处理脚本”轻巧等效。

有一个子程序:

:reset_error
exit /b 0

然后就

call :reset_error

无论您在何处需要它。

这是一个完整的示例:

@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

哪个输出:

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

如您所见-仅通过goto:eof调用并返回还不够。


2

这是其他一些重置ErrorLevel状态的方法,甚至在MS-DOS中也可以(至少对于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

以下方法仅在MS-DOS中起作用:

command /? > nul

fc nul nul > nul

keyb > nul

为了完整起见,这会将ErrorLevel状态设置为1,对Windows和MS-DOS均有效:

< nul find ""

1

以下功能在具有以下功能的现代Windows(基于NT)系统中起作用cmd.exe

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

SPACE(或更确切地说,一个或多个标准的令牌分离器,它们是任意的序列SPACE(码0x20), TAB(代码0x09), ,,;=NBSP代码0xFF), VTAB(代码0x0B)和FF(码0x0C))是强制的; 如果您忽略它,ErrorLevel则改为设置:

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

DosTips.com上有一个不错的线程,该技术就出现了。


这是另一种方法,但是它访问文件系统,因此可能会慢一些:

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

0

>nul在每个可能失败的命令之后添加-这似乎可以防止构建失败。

您仍然可以通过检查来检查命令的结果%errorlevel%

例如:

findstr "foo" c:\temp.txt>nul & if %errorlevel% EQU 0 (echo found it) else (echo didn't find it)

2
这将行不通-shell会立即评估整个命令行,因此%errorlevel%将在执行“ findstr”命令之前被替换。使用“如果错误级别1”代替测试非零错误级别。
UweBaemayr

2
例如,如果您的CI服务器在标准输出/标准错误中找到字符串“错误”,则构建可能会失败。您没有重置状态。您只是使命令静音。要更深地保持沉默,请使用> nul 2> nul
Tomasz Gandor

0

复习所有其他答案后,我决定找到哪种方法最有效地重置ERRORLEVEL。我制作了一个快速脚本,记录了执行每个脚本的时间:

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

这是输出:

cmd / v:on / c set ^“ q = ^” ^“&timeit.cmd” cmd / c ^!q ^!exit / b 0 ^!q ^!“” cd“” ver“”类型nul“ “校验”

cmd / c“退出/ b 0”采取了0:0:0.02(总计0.02s)

光盘 花费了0:0:0.00(共0.00秒)

Microsoft Windows [版本10.0.18362.836]

ver采取了0:0:0.00(共0.00s)

nul类型花费了0:0:0.00(总共0.00s)

验证已关闭。验证时间为0:0:0.00(总计0.00秒)


这花费了0:0:0.06(总共0.06s)

Measure-Command {command}在Powershell中使用with进行审查后,我发现它只是被真正接受了cd .cmd /c "exit /b 0"我做错了吗?

我建议要么cd .还是type nul因为无论对控制台的输出足迹,也不会在任何程度放缓。

是的,我很无聊


是的,cmd /C exit [/B] 0应该是自cmd.exe打开和关闭新实例以来最慢的时间;其他都是内部命令,因此没有文件系统访问权限来查找可执行文件……
aschipfl


-5

我一直都习惯

set ERRORLEVEL=0

我已经使用它多年的驴。


29
这很容易,但确实是个坏主意,因为这会创建一个名为的变量,该变量errorlevel会覆盖内部伪变量errorlevel
jeb 2014年

6
key,你是对的!哇,看起来我已经躲避子弹多年了:)
卷云
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.