FOR IN() 子句中的命令在全新的 CMD.EXE 会话中运行,因此无法直接访问 ERRORLEVEL 或命令可能设置的任何环境变量。
通常最好和最简单的解决方案是使用临时文件:
yourCommand >output.txt
set exit_code=%errorlevel%
for /f "delims=" %%i in (output.txt) do processOutput
del output.txt
但是您已声明不能使用临时文件。
唯一的选择是在 IN() 子句中回显 ERRORLEVEL,然后在 DO 子句中解析 ERRORLEVEL。回显 ERRORLEVEL 有点棘手,因为 %ERRORLEVEL% 在解析时被扩展,并且整个 IN() 子句被一次解析,因此 %ERRORLEVEL% 将始终为 0。
IN() 子句命令使用命令行上下文执行,而不是批处理上下文。新的 CMD.EXE 会话不会继承当前的延迟扩展状态 - 它默认为禁用延迟扩展。最简单的解决方案是使用 CALL 和适当的转义%ERRORLEVEL%
来延迟扩展,直到您的命令执行之后。添加插入符号以转义命令上下文。然后百分比和插入符号加倍以逃避父批次 - %%^^ERRORLEVEL%%
。
您需要使您的 ERRORLEVEL 消息唯一,以便您的 DO 子句可以将 ERRORLEVEL 与正常输出区分开来。
@echo off
setlocal enableDelayedExpansion
for /f "delims=" %%A in ('dir DoesNotExist^&call echo ::ERROR::%%^^ERRORLEVEL%%') do (
set "ln=%%A"
if "!ln:~0,9!" equ "::ERROR::" (
set "EXIT_CODE=!LN:~9!"
) else (
REM normal output - do whatever
echo %%A
)
)
echo EXIT_CODE=%EXIT_CODE%
这是上面的一些示例输出
C:\test>test.bat
File Not Found
Volume in drive C is OS
Volume Serial Number is EE2C-5A11
Directory of C:\test
EXIT_CODE=1