2012-06-23 50 views

回答

22

你可能認爲你可以做類似下面的事情,但它不會工作。

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

問題在於Windows管道工作的機制。管道的每一側都在它自己的CMD外殼中執行。因此,您設置的任何環境變量將在命令完成後消失。此外,%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?。我建議閱讀這個問題和所有的答案。所選答案有最佳信息,但其他答案有助於提供上下文。

EDIT 2015年6月2日

我最近發現可以使用DOSKEY宏乾淨商店,並通過管道,無論(或兩者)雙方檢索錯誤級別,而不訴諸臨時文件。我從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 /f "tokens=2 delims==" %%A in ('doskey /m:err') do echo nmake returned %%A 

如果你願意,你可以在最後添加一個命令來清除Err「宏」的定義您檢索後值。

doskey /exename=err err= 
+0

簡單的解決方案打破了使用三通(同時輸出)的主要原因。對於第一種解決方案,您可以使用「set/p MY_ERROR =

+0

「call set」,「call echo」等是什麼處理?我從來沒有見過這種語法。 – alecov

+1

@Alek - 在初始解析後獲得第二輪變量擴展是一種老式的攻擊。這是使用延遲擴展的替代方法。 'echo!var!'類似於'call echo %% var %%'。延遲擴展通常是首選,但有時需要CALL破解。 – dbenham