Windows命令解释器:如何获取第一个管道命令的退出代码

在下面提供的示例中,我执行nmake,然后将STDOUT / STDERR重定向到发球台,然后将其发送到屏幕,并将其发送到日志文件.
问题是我试图捕获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=

相关文章

Windows2012R2备用域控搭建 前置操作 域控主域控的主dns:自...
主域控角色迁移和夺取(转载) 转载自:http://yupeizhi.blo...
Windows2012R2 NTP时间同步 Windows2012R2里没有了internet时...
Windows注册表操作基础代码 Windows下对注册表进行操作使用的...
黑客常用WinAPI函数整理之前的博客写了很多关于Windows编程的...
一个简单的Windows Socket可复用框架说起网络编程,无非是建...