2012-06-23 10 views

Odpowiedz

22

Możesz myśleć, że możesz zrobić coś podobnego, ale to nie zadziała.

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

Problem leży w mechanizmie działania przewodów systemu Windows. Każda strona rury jest wykonywana we własnej powłoce CMD. Tak więc ustawiona tam zmienna środowiskowa zniknie po zakończeniu polecenia. Również opóźniona ekspansja% errorlevel% jest bardziej skomplikowana z powodu dodatkowego poziomu parsowania, a ponieważ powłoka CMD ma kontekst wiersza poleceń zamiast kontekstu wsadowego.

Można zrobić coś takiego:

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

Albo można osadzić ERRORLEVEL w 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 

Ale najprostszym rozwiązaniem wydaje się być

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


Uwaga - podczas pracy z systemami Windows występuje wiele subtelnych komplikacji. Dobry odnośnik to Why does delayed expansion fail when inside a piped block of code?. Polecam przeczytanie pytania i wszystkich odpowiedzi. Wybrana odpowiedź ma najlepsze informacje, ale inne odpowiedzi pomagają zapewnić kontekst.

EDIT 2015-06-02

I niedawno odkryto można użyć makra DOSKEY do czysto przechowywać i pobierać ERRORLEVEL albo (lub obu) stronach rury, bez uciekania się do plik tymczasowy. Mam pomysł od DosTips użytkownika Ed Dyreen na http://www.dostips.com/forum/viewtopic.php?p=41409#p41409. Makra DOSKEY nie mogą być wykonywane przez wsad, ale definicje nadal występują po zakończeniu ENDLOCAL i CMD/C!

Oto jak można go używać w danej sytuacji:

(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 

Jeśli chcesz, możesz dodać jeszcze jedno polecenie na koniec, aby usunąć definicję Err „makro” po pobraniu wartość.

doskey /exename=err err= 
+0

Proste rozwiązanie eliminuje główny powód używania trójnika (równoczesne wyjście). Również dla pierwszego rozwiązania możesz użyć "set/p MY_ERROR =

+0

Co to jest umowa z 'call set',' call echo' i tak dalej? Nigdy wcześniej nie widziałem tej składni. – alecov

+1

@Alek - Jest to stary hack, aby uzyskać drugą rundę zmiennej ekspansji po początkowym przeanalizowaniu. Jest to alternatywa dla opóźnionego rozszerzenia. 'echo! var!' jest podobne do 'call echo %% var %%'. Opóźniona ekspansja jest zazwyczaj preferowana, ale zdarzają się sytuacje, gdy potrzebny jest hackowanie CALL. – dbenham