我有一个命令(让我们称之为command
)打印到标准输出,并且还会根据执行的成功或失败设置ERRORLEVEL。我想从将处理command
输出的批处理脚本中调用command
,但仅当command
以ERRORLEVEL为0(即成功)退出时。这样做最好不需要临时文件或检查命令的输出来推断它是否成功。
我能够使用for
语句捕获命令的输出,但是在执行此操作时我无法检查ERRORLEVEL。我尝试过类似的东西:
for /F %%A in ('command') do (
REM The following check does not seem to work
if ERRORLEVEL 1 goto error
REM otherwise, do stuff with %%A
)
我也尝试过使用%errorlevel%
和!errorlevel!
(使用setlocal enabledelayedexpansion
),但都没有效果。
答案 0 :(得分:1)
使用如下代码:
@echo off
"command.exe">"%TEMP%\CommandOutput.tmp"
if errorlevel 1 goto Failed
for /F "usebackq" %%A in ("%TEMP%\CommandOutput.tmp") do (
REM Do stuff with %%A
echo %%A
)
goto DelTempFile
:Failed
echo There was an error on executing command.
:DelTempFile
if exist "%TEMP%\CommandOutput.tmp" del "%TEMP%\CommandOutput.tmp"
此批处理代码首先运行命令,将标准输出重定向到临时文件的文件夹中的文件。接下来,它会评估命令的退出代码。
如果没有错误,则使用 处理输出。
错误会显示相应的错误消息。
最后,在批处理终止之前删除带有捕获输出的临时文件。
答案 1 :(得分:0)
问题是在in
命令的for
子句中执行的命令在单独的cmd
实例中运行,并且该实例的退出代码不会传播到代码在do
子句中。
如果您需要for
命令来处理输出,并且需要errorlevel
子句中的spawned命令的do
,则需要将两者分开并生成临时文件。
Mofi的答案可能是最快,最简单,更直接的解决方案,无需涉及外部脚本引擎/ powershell。
对于大多数代码包含在in
子句中的解决方案:
@echo off
setlocal enableextensions disabledelayedexpansion
rem Some commands for testing - command/uncomment as needed
set "command=findstr 2> nul"
rem set "command=ping -n 1 localhost"
rem set "command=ping -n 1 localhost | find "TTL^^^=" "
set "el="
for /f "delims=" %%a in ('
cmd /v /q /c "set "t^=%temp%\%~nx0.%random%"&(>"!t!" (%command%)&echo(!errorlevel!&type "!t!"&del /q "!t!")"
') do if not defined el (
rem The first line in the output is the exit code of the executed command
set "el=%%a" & if %%a gtr 0 goto failed
) else (
rem Process the output of the command
echo(%%a
)
exit /b
:failed
echo failed with errorlevel %el%
goto :eof
基本思路是将errorlevel作为执行命令输出的第一行,这样我们就可以检查它并决定是否需要更多处理。
注意:这不会避免必须将所有输出加载到内存中。 for /f
在开始执行do
子句中的代码之前加载所有数据,并且在从命令执行的文件中检索数据时效率更高(其中一个原因是来自Mofi的答案更快)