cmd命令行中的errorlevel和延迟赋值

最近用到了命令行,一点心得:

1、errorlevel返回的确实是上一条命令的返回值,但不同命令的表现完全不同。比如:

 1 dir
 2 echo %errorlevel%  //显示0
 3 dir aldkalf               // 不存在的文件名
 4 echo %errorlevel%  // 显示1
 5 
 6 set /a test=0/0        // 除0错误
 7 echo %errorlevel%  // 显示1073750993
 8 set test=lala           //  正确!
 9 echo %errorlevel%  // 结果还是显示上面那个错误号
10 set /a test=10%%%2  //  换个求余的错误:找不到操作数
11 echo %errorlevel%  // 显示10737500989,注意和上面那个错误码不同了!

dir的表现很符合直觉,但set只有在错误时才会去修改errorlevel,其他命令的表现也各有各的不同,使用时一定要亲自试试。

2、延迟赋值在for循环里尤其容易出问题。比如下面这段,我希望生成出错,就跳出循环:

1 for %%i in (a.csproj, b.csproj) do (
2     msbuild %%i
3     if not %errorlevel% == 0 goto break
4 )

结果却是总是正确的,永远不会中途跳出循环。原因是cmd认为for是一条语句,只有在整个for循环执行完、并退出for之后,才会将最后一次msbuild的错误码赋给errorlevel。如果希望每次就能获取最新的errorlevel,应该如下:

1 SetLocal EnableDelayedExpansion
2 for %%i in (a.csproj, b.csproj) do (
3     msbuild %%i
4     if not !errorlevel! == 0 goto break
5 )