32

批处理文件默认返回最后一条命令的错误码。

是否有可能返回前一个命令的错误代码。最值得注意的是,是否可以在管道中返回命令的错误代码?

例如,这个单行批处理脚本

foo.exe

返回foo的错误代码。但是这个:

foo.exe | tee output.txt

总是返回tee的退出代码,该代码为零。

4

6 回答 6

11

我遇到了类似的问题并选择了以下解决方案,因为我不需要检测确切的错误代码只是成功或失败。

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
)
于 2014-10-05T21:05:37.830 回答
2

%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% 似乎不一致。

编辑:将示例更改为可按原样运行。

于 2011-10-06T19:22:42.833 回答
2

一种解决方法是通过文件进行间接寻址。

像这样

foo.exe > tmp.txt
set FOOERR=%ERRORLEVEL%
cat tmp.txt
exit %FOOERR%
于 2009-05-18T13:38:28.613 回答
2

经过大约一天的挖掘,我找到了一种方法:

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/stdout/stderr 分配的图表,以了解它的作用:-))。我没有找到提取实际错误级别的好方法。我得到的最好的事情是用一些批处理脚本调用'call rc.bat'替换'echo'命令,它看起来像:

@echo %errorlevel%

然后将 'set error_=1' 替换为 'set error_=%%i'。

但问题是这个调用也可能失败,而且不容易检测到。尽管如此,它总比没有好 - 我在互联网上没有找到任何解决方案。

于 2010-01-02T03:50:20.323 回答
2

要为入口 bat 文件调用 tee,而不是为单个命令调用,并自由使用 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 与调用批处理中的任何命令分开。

于 2016-12-28T14:18:28.863 回答
1

您可以通过在命令文件周围创建包装器来解决此问题:

rem wrapper for command file, wrapper.cmd

call foo.exe

echo %errorlevel%

if errorlevel 1 goto...

然后将 tee 附加到包装器:

wrapper.cmd | tee result.log

当然,这并不完全相同,例如,如果您想在打包文件中登录多个文件,这是不可能的,但在我的情况下它解决了问题。

于 2010-07-15T10:21:26.363 回答