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

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

问题描述

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

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

问题在于 Windows 管道的工作机制.管道的每一侧都在它自己的 CMD shell 中执行.因此,一旦命令完成,您在那里设置的任何环境变量都会消失.此外,%errorlevel% 的延迟扩展更加复杂,因为额外的解析级别,并且因为 CMD shell 具有命令行上下文而不是批处理上下文.

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.

你可以这样做:

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

或者您可以在 output.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

上述两种解决方案都假设您在批处理脚本中运行命令.如果您是从命令行执行命令,则上述两种解决方案都需要
%^^errorlevel% 而不是 %%^^errorlevel%%.

Both solutions above assume you are running the commands in a batch script. If you are executing the commands from the command line instead, then both solutions above need
%^^errorlevel% instead of %%^^errorlevel%%.

但鉴于 nmake 不需要用户输入,而且它通常很快,所以实时监控可能不是问题,那么最简单的解决方案似乎是

But given that nmake does not require user input, and it is usually fast so real time monitoring is probably not an issue, then the simplest solution seems to be

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


注意 - 使用 Windows 管道时有许多微妙的复杂性.一个很好的参考是为什么在管道代码块中延迟扩展会失败?.我建议阅读问题和所有答案.所选答案具有最佳信息,但其他答案有助于提供上下文.


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.

编辑 2015-06-02

我最近发现您可以使用 DOSKEY 宏从管道的任一侧(或两侧)干净地存储和检索 ERRORLEVEL,而无需求助于临时文件.我从 DosTips 用户 Ed Dyreen 在 http://www.dostips.com/forum/viewtopic.php?p=41409#p41409.DOSKEY 宏无法批量执行,但ENDLOCAL 和CMD/C 退出后定义仍然存在!

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天全站免登陆