FOR / F命令循环中的ERRORLEVEL返回意外的结果

我正在尝试loggingnet stop的输出,同时还捕获其错误。

基于这个问题 ,我尝试了嵌套子例程中的以下内容:

 set /a loopIndex=0 for /F "usebackq delims=" %%i in (`net stop %SERVICE_NAME%`) do ( if !loopIndex! EQU 0 if !errorlevel! EQU 1 set statementError=1 set /a loopIndex+=1 call :logMessage "%%i" ) echo statementError: %statementError% 

然而,这是行不通的,即使net stop成功,也会抛出1

这可能没有临时文件? 如果没有,临时文件解决scheme是什么样的?

Solutions Collecting From Web of "FOR / F命令循环中的ERRORLEVEL返回意外的结果"

虽然@ dbenham的答案适用于%ERRORLEVEL%返回二进制值的情况,但我无法确认也不否认,如果返回的net stop退出代码事实上是二进制的,并且选择了n元解决方案。

根据@ dbenham的DOS提示论坛帖子 :

 FOR /F "delims=" %%i IN ('net stop MyService 2^>^&1 ^& CALL ECHO %%^^ERRORLEVEL%%^>error.level') DO ( CALL :logMessage "%%i" ) FOR /F "delims=" %%i IN (error.level) DO (SET /A statementError=%%i) DEL error.level IF %statementError% NEQ 0 () 

分解语句解析:

 net stop MyService 2^>^&1 ^& CALL ECHO %%^^ERRORLEVEL%%^>error.level 
 net stop MyService 2>&1 & CALL ECHO %^ERRORLEVEL%>error.level 
 echo %ERRORLEVEL%>error.level 

这里, CALL特别用于延迟解析%ERRORLEVEL%直到执行ECHO

FOR / F命令在新的cmd.exe进程中执行NET STOP。 FOR / F处理stdout,但就是这样。 主脚本无法查看FOR / F命令可能创建的任何变量值,因为一旦子进程终止,它们就会消失。

最简单和最有效的解决方案使用临时文件。 我假设NET STOP有两个可能的错误代码 – 成功= 0,错误= 1。所以最简单的解决方案是简单地创建一个临时的错误信号文件,如果有错误。

下面以通用的方式演示这个概念:

 @echo off del error.flag 2>nul for /f "delims=" %%A in ('net stop %SERVICE_NAME% ^|^| echo error>error.flag') do ( ... ) if exist error.flag ( echo There was an error del error.flag ) 

如果需要,您可以轻松将错误测试放在DO()代码中。