Windows命令解释器:如何获取第一个管道命令的退出代码 [英] Windows command interpreter: how to obtain exit code of first piped command

查看:253
本文介绍了Windows命令解释器:如何获取第一个管道命令的退出代码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在下面提供的示例中,我执行nmake,然后将STDOUT / STDERR重定向到tee,然后将其发送到屏幕以及日志文件。
问题是,我试图捕获nmake和不是tee的退出代码。
我需要的是nmake的退出代码,而不是tee。

  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返回%% A
del myError.txt

或者你可以在你的output.txt中嵌入错误级别:

  (nmake& call echo nmakeReturnCode:%% ^^ errorlevel %%)| tee output.txt 
for / ftokens = 2%% A in('findstr / bnmakeReturnCode:output.txt)do echo nmake返回%% A
  

> nmake> output.txt
set myError =%errorlevel%
type output.txt
echo nmake返回%myError%



注意 - 使用Windows管道时有许多微妙的复杂情况。一个很好的参考是为什么在管道代码块中延迟扩展失败?。我建议阅读问题和所有的答案。



编辑2015-06-02 >



我最近发现你可以使用DOSKEY宏从一个管道的(或两个)端干净地存储和检索ERRORLEVEL,而不诉诸于临时文件。我在DosTips用户Ed Dyreen的想法是 http://www.dostips.com/forum/ viewtopic.php?p = 41409#p41409 。 DOSKEY宏不能通过批处理执行,但定义在ENDLOCAL和CMD / C退出后仍然存在!



这里是如何在你的情况下使用它:

 (nmake& call doskey / exename = err err = %% ^^ errorlevel %%)| tee output.txt 
for / ftokens = 2 delims ==%% A in('doskey / m:err')do echo nmake returned %% A

如果需要,您可以在检索该值后在末尾添加一个命令以清除错误宏的定义。 p>

  doskey / exename = err err = 


In the example provided below, I execute nmake and then redirect STDOUT/STDERR to tee, which then sends it to the screen, and also to a log file. The problem is that I'm trying to capture the exit code for nmake and not tee. What I need is the exit code from nmake, and not tee.

nmake | tee output.txt

解决方案

You might think you could do something like the following, but it won't work.

(nmake & call set myError=%%errorlevel%%) | tee output.txt

The problem lies in the mechanism by which Windows pipes work. Each side of the pipe is executed in it's own CMD shell. So any environment variable you set there will disappear once the command has finished. Also the delayed expansion of %errorlevel% is more complicated because of the extra level of parsing, and because the CMD shell has a command line context instead of a batch context.

You could do something like this:

(nmake & call echo %%^^errorlevel%% ^>myError.txt) | tee output.txt
for /f %%A in (myError.txt) do echo nmake returned %%A
del myError.txt

Or you could embed the errorlevel in your 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

But the simplest solution seems to be

nmake >output.txt
set myError=%errorlevel%
type output.txt
echo nmake returned %myError%


Note - there are many subtle complications when working with Windows pipes. A good reference is Why does delayed expansion fail when inside a piped block of code?. I recommend reading the question and all the answers. The selected answer has the best info, but the other answers help provide context.

EDIT 2015-06-02

I've recently discovered you can use DOSKEY macros to cleanly store and retrieve the ERRORLEVEL from either (or both) sides of a pipe, without resorting to a temporary file. I got the idea from DosTips user Ed Dyreen at http://www.dostips.com/forum/viewtopic.php?p=41409#p41409. DOSKEY macros cannot be executed via batch, but the definitions persist after ENDLOCAL and CMD /C exit!

Here is how you would use it in your situation:

(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

If you want, you can add one more command at the end to clear the definition of the err "macro" after you have retrieved the value.

doskey /exename=err err=

这篇关于Windows命令解释器:如何获取第一个管道命令的退出代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆