batch file默认返回最后一个命令的错误代码。
是否有可能返回以前的命令的错误代码。 最值得注意的是,是否可以返回pipe道中命令的错误代码?
例如,这个一行批处理脚本
foo.exe
返回foo的错误代码。 但是这个:
foo.exe | tee output.txt
总是返回T的退出代码,这是零。
一种解决方法是通过文件进行间接寻址。
喜欢这个
foo.exe > tmp.txt set FOOERR=%ERRORLEVEL% cat tmp.txt exit %FOOERR%
我有一个类似的问题,解决了以下解决方案,因为我不需要检测确切的错误代码,只是成功或失败。
echo > .failed.tmp ( foo.exe && del .failed.tmp ) | tee foo.log if exist .failed.tmp ( del .failed.tmp exit /b 1 ) else ( exit /b 0 )
管道命令运行之前,%ERRORLEVEL%变量不会被更新; 你必须使用其他答案中建议的包装。
但是,您可以使用“IF ERRORLEVEL#”。 例如:
( type filename @REM Use an existing (or not) filename to test each branch IF ERRORLEVEL 1 (echo ERROR) ELSE (echo OKAY) ) > logfile.txt
只有返回错误时,ECHO才会运行。 但%ERRORLEVEL%似乎不一致。
编辑:更改示例为可运行的。
大约一天的挖掘之后,我找到了一个办法:
set error_=0 9>&1 1>&2 2>&9 (for /f "delims=" %%i in ('9^>^&1 1^>^&2 2^>^&9 ^(^(^(2^>^&1 call "%homeDir%%1"^) ^|^| ^(1^>^&2 2^>nul echo FAILED^)^) ^| 2^>nul "%homeDir%mtee" /T /+ "%homeDir%logs\%date_%_%1.log"^)') do (set error_=1)) exit /b %error_%
在上面的例子中,“%homeDir %% 1”正在执行,其输出被传送到“%homeDir%mtee”。 这一行检测失败(我建议你绘制一个批处理上下文和stdin /标准输出/ stderr分配的图表,以了解它是什么:-))。 我没有找到提取实际错误级别的好方法。 我得到的最好的东西是用一些批处理脚本调用'call rc.bat'替换'echo'命令,它看起来像:
@echo %errorlevel%
然后用'set error _ = %% i'替换'set error_ = 1'。
但问题是,这个调用可能会失败,而且不容易检测到。 尽管如此,它总比没有好 – 我在互联网上没有找到任何解决方案。
你可以通过在你的命令文件中创建一个包装来解决这个问题:
rem wrapper for command file, wrapper.cmd call foo.exe echo %errorlevel% if errorlevel 1 goto...
然后将三通附加到包装上:
wrapper.cmd | tee result.log
当然这并不完全一样,例如,如果你想在包装文件中登录几个文件,这是不可能的,但在我的情况下,它解决了这个问题。
要调用输入bat-file,而不是单个命令,并自由地使用errorlevel,我使用这样的技巧:
if "%1" == "body" goto :body call %0 body | tee log.txt goto :eof :body set nls_lang=american_america set HomePath=%~dp0 sqlplus "usr/pwd@tnsname" "@%HomePath%script.sql" if errorlevel 1 goto dberror rem Here I can do something which is dependent on correct finish of script.sql :dberror echo script.sqlerror failed
它使用tee从批量调用任何命令分离。