DOS 批处理脚本 return 代码未 return 发送给调用者

DOS Batch script return code not being returned to caller

我们有一个 file1.cmd 调用 file2.cmd 调用 file3.cmd。

file3.cmd returns 失败为:exit /b 1

但是在file2.cmd我们似乎"lose"这个失败代码。 %ERRORLEVEL% 变量被列为 0 而不是 1。

有什么想法吗?

可以发现的常见问题:

正在将 errorlevel 变量设置为一个值

set errorlevel=0
echo test | find "x" > nul 2>nul
echo %errorlevel%

此处将设置错误级别(find 操作失败)但回显到控制台的值将为 0。errorlevel 是一个动态变量并为其设置值会阻止访问到动态值。 errorlevel 值不应使用 set 命令设置。

如果需要设置错误级别可以

  • 离开 运行 批次时:exit nexit /b n
  • 在 运行 批次内,不离开它:cmd /c exit n

在这两种情况下,n 在错误级别中设置的数值

要清除错误级别,您可以使用:ver>nul

变量展开

if 1==1 (
    echo test | find "x" > nul 2>nul
    if %errorlevel%==1 echo failed
)

当批解析器到达一行或一行块(括号中的行)时,它会用变量内部的值替换所有对变量的读取操作before执行line/block。因此,如果变量在 line/block 中更改了它的值,则无法从同一个 line/block 中检索到新值。读取操作不存在,已替换为初始值

可以启用延迟扩展,允许(在需要时)将语法从 %var% 更改为 !var!,指示解析器必须延迟读取操作直到命令执行

setlocal enabledelayedexpansion
if 1==1 (
    echo test | find "x" > nul 2>nul
    if !errorlevel!==1 echo failed
)

但是对于前面两种情况中的任何一种,都有一个替代方案。批处理语言包括一个结构来测试不受赋值或变量扩展影响的错误级别

if errorlevel n .....

对于任何大于或等于 n 的错误级别,此构造将被评估为真。出于这个原因,当使用这个构造并测试不同的错误级别时,有必要测试 errorlevel 从大到小的值

if errorlevel 3 (
    ....
) else if errorlevel 2 (
    ....
) else if errorlevel 1 ( 
    ....
) else (
  ....
)

在唯一检查是否设置错误级别的情况下,可以使用条件执行来简化此构造

command && ( .... ) || ( .... )

其中&&后的命令在未设置errorlevel时执行,||后的命令在设置errorlevel时执行