在下面提供的示例中,我執行nmake,然後將STDOUT/STDERR重定向到tee,然後將它發送到屏幕以及日誌文件。 問題是,我試圖捕獲nmake的退出碼而不是tee。 我需要的是nmake的退出代碼,而不是三通。Windows命令解釋器:如何獲得第一個管道命令的退出代碼
nmake | tee output.txt
在下面提供的示例中,我執行nmake,然後將STDOUT/STDERR重定向到tee,然後將它發送到屏幕以及日誌文件。 問題是,我試圖捕獲nmake的退出碼而不是tee。 我需要的是nmake的退出代碼,而不是三通。Windows命令解釋器:如何獲得第一個管道命令的退出代碼
nmake | tee output.txt
你可能認爲你可以做類似下面的事情,但它不會工作。
(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=
簡單的解決方案打破了使用三通(同時輸出)的主要原因。對於第一種解決方案,您可以使用「set/p MY_ERROR =
「call set」,「call echo」等是什麼處理?我從來沒有見過這種語法。 – alecov
@Alek - 在初始解析後獲得第二輪變量擴展是一種老式的攻擊。這是使用延遲擴展的替代方法。 'echo!var!'類似於'call echo %% var %%'。延遲擴展通常是首選,但有時需要CALL破解。 – dbenham