在下面提供的示例中,我执行nmake,然后将STDOUT / STDERR重定向到发球台,然后将其发送到屏幕,并将其发送到日志文件.
问题是我试图捕获nmake而不是tee的退出代码.
我需要的是nmake的退出代码,而不是三通.
问题是我试图捕获nmake而不是tee的退出代码.
我需要的是nmake的退出代码,而不是三通.
nmake | tee output.txt
你可能会认为你可以做如下的事情,但是不行.
(nmake & call set myError=%%errorlevel%%) | tee output.txt
问题在于Windows管道工作的机制.管道的每一边都在自己的CMD shell中执行.所以你设置的任何环境变量都将在命令完成后消失.此外,%errorlevel%的延迟扩展更复杂,因为额外的解析级别,并且因为CMD shell具有命令行上下文而不是批处理上下文.
你可以这样做:
(nmake & call echo %%^^errorlevel%% ^>myError.txt) | tee output.txt for /f %%A in (myError.txt) do echo nmake returned %%A del myError.txt
或者您可以将errorlevel嵌入到您的output.txt中:
(nmake & call echo nmakeReturnCode: %%^^errorlevel%%) | tee output.txt for /f "tokens=2" %%A in ('findstr /b "nmakeReturnCode:" output.txt') do echo nmake returned %%A
但最简单的解决方案似乎是
nmake >output.txt set myError=%errorlevel% type output.txt echo nmake returned %myError%
注意 – 使用Windows管道时有许多微妙的并发症.一个很好的参考是Why does delayed expansion fail when inside a piped block of code?.我建议阅读问题和所有的答案.选择的答案有最好的信息,但其他答案有助于提供上下文.
编辑2015-06-02
我最近发现可以使用DOSKEY宏来从管道的两侧(或两端)清理地存储和检索ERRORLEVEL,而不需要使用临时文件.我从DosTips用户Ed Dyreen得到了这个想法.DOSKEY宏不能通过批处理执行,但定义在ENDLOCAL和CMD / C退出后仍然存在!
以下是您如何使用它在您的情况:
(nmake & call doskey /exename=err err=%%^^errorlevel%%) | tee output.txt for /f "tokens=2 delims==" %%A in ('doskey /m:err') do echo nmake returned %%A
如果需要,您可以在结束后再添加一个命令,以便在检索到该值后清除err“宏”的定义.
doskey /exename=err err=