【问题标题】:What is the easiest way to reset ERRORLEVEL to zero?将 ERRORLEVEL 重置为零的最简单方法是什么?
【发布时间】:2023-03-08 17:35:02
【问题描述】:

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

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

【问题讨论】:

  • 构建并没有真正失败,只是 IDE 看起来确实如此。
  • 我意识到这是一篇相当老的帖子......我通过在最后一个命令之后发出命令“type nul”成功地将错误级别重置为 0。只是觉得它可能有用。

标签: windows batch-file cmd errorlevel


【解决方案1】:

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

【讨论】:

  • 在所有建议的解决方案中,这可能是最好的一个。我将把这一行放入一个 resetErrorlevel.bat 脚本中。总而言之,一个人必须不遗余力地做一些微不足道的事情,比如清除脚本的错误级别,这进一步证明了 Windows 批处理编程的发明者应该受到严厉的追捕和惩罚。 ;)
【解决方案2】:

似乎可以解决问题:

ver > nul

并非一切都有效,目前尚不清楚原因。例如,以下内容不会:

echo. > nul
cls > nul

【讨论】:

  • 我认为“echo”和“cls”不起作用的原因是因为它们是shell内置命令,而不是真正的程序。
  • 我会给你,但是ver.exe在哪里?
  • 在批处理命令行中,“ver”返回 MS windows 版本,例如“Microsoft Windows [Version 6.1.7601]”。
  • 如果你在命令shell中运行帮助,你会看到ver也是一个内置命令
  • @BaiyanHuang - 我几乎肯定"ver" 是一个内部命令,但你怎么能从"help" 中看出呢? "help" 中列出的许多命令都是“外部”命令,例如:Find.exeFindstr.exeHelp.exeSubst.exeWmic.exeXcopy.exe、...
【解决方案3】:

在构建前或构建后事件中,如果可执行文件的返回码大于零,并且对可执行文件的调用不是构建前或构建后事件的最后一行,则可以快速将其静音并避免触发对非零的检查 errorlevel 是在失败的行后面加上明确返回零的行:

cmd /c "exit /b 0"

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

【讨论】:

  • 谢谢,这对我有用。上面“退出 0”的更简单的建议并没有削减它,因为我希望在重置错误级别后继续做事情,而不是退出
  • 更花哨:您可以将<some failing command> || cmd /c "exit /b 0" 用作一个衬里。
  • 我喜欢这种方法来设置任意错误级别,例如:cmd /c "exit /b 9009",但将其设置为 0 似乎有点矫枉过正。不会't ver > nul(一个内部命令),与使用 cmd /c "exit /b 0" 加载另一个命令 shell 副本相比,开销更少?
  • 不需要/b,所以cmd /c “exit 0”也可以正常工作。
  • 我喜欢这个工作。谢谢。一件有趣的事情是我正在跟踪某个文件并且我的错误级别一直更改为 1,最后我发现提示用户喜欢 (set /p id="enter id") 将错误级别更改为 1! ...我已经填满了b
【解决方案4】:

我个人使用这个:

cd .

即使在 unix shell 中也能工作。

但是,这个可能会快一点:

type nul>nul

因为Process Monitor 显示QueryDirectory 调用cd .

PS: cd . 在 unix shell 中有另一个很好的副作用。如果在擦除之前已打开它,它确实会在终端中恢复重新创建的工作目录。

更新

而且这样更快一点:

call;

https://www.dostips.com/forum/viewtopic.php?t=5542

【讨论】:

    【解决方案5】:

    我发现“exit 0”看起来是处理这个问题的好方法。

    用法示例:

    NET STOP UnderDevService /Y

    退出 0

    如果 UnderDevService 服务没有启动。

    【讨论】:

    • 如果您还想从命令行运行该批处理文件,则不是,因为 exit 0 将关闭窗口。如下建议的 cmd /c "exit /b 0" 更方便
    【解决方案6】:

    我使用VERIFYVERIFY > nul

    【讨论】:

      【解决方案7】:

      如果这是一个类似“构建后事件”等的 sn-p,那么你可以添加:

      (...) || 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 调用和返回是不够的。

      【讨论】:

        【解决方案8】:

        以下适用于具有cmd.exe 的现代 Windows(基于 NT)系统:

        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
        

        【讨论】:

          【解决方案9】:

          这里有一些其他方法可以重置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 ""
          

          【讨论】:

            【解决方案10】:

            在查看了所有其他答案后,我决定找出重置 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 "exit /b 0" 耗时 0:0:0.02(总共 0.02 秒)

            光盘。耗时 0:0:0.00(总共 0.00 秒)

            Microsoft Windows [版本 10.0.18362.836]

            ver 耗时 0:0:0.00(总共 0.00 秒)

            type nul 耗时 0:0:0.00(总共 0.00 秒)

            验证已关闭。 VERIFY 耗时 0:0:0.00(总共 0.00 秒)


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

            在Powershell中使用Measure-Command {command}查看后,我发现它只接受cd .cmd /c "exit /b 0"——我做错了吗?

            我推荐cd .type nul,因为它们都不会影响控制台的输出,而且它们在任何方面都不会变慢。

            是的,我很无聊

            【讨论】:

            • 是的,cmd /C exit [/B] 0 应该是最慢的,因为新的cmd.exe 实例被打开和关闭;其他都是内部命令,所以没有文件系统访问权限来查找可执行文件……
            【解决方案11】:

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

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

            例如:

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

            【讨论】:

            • 这行不通——shell 会立即评估整个命令行,因此在执行“findstr”命令之前将替换 %errorlevel%。改用“if errorlevel 1”来测试非零错误级别。
            • 如果 CI 服务器在标准输出/标准错误中找到字符串“error”,则可能会导致构建失败。您没有重置状态。您只是在使命令静音。要获得更深的沉默,请使用 >nul 2>nul
            【解决方案12】:

            我正在使用这个:

            ping localhost -n 1 >null

            【讨论】:

              【解决方案13】:

              我一直只是用;

              set ERRORLEVEL=0
              

              我已经用了这么多年了。

              【讨论】:

              • 这很简单,但这是一个非常糟糕的主意,因为这会创建一个名为 errorlevel 的变量,它会覆盖内部伪变量 errorlevel
              • Crikey,你是对的!哇,看起来我多年来一直在躲子弹:)
              猜你喜欢
              • 2017-01-27
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2014-05-09
              • 2013-12-30
              • 2021-03-25
              相关资源
              最近更新 更多