Mam plik wsadowy, który w kółko wywołuje ten sam plik wykonywalny z różnymi parametrami. Jak sprawić, by zakończyło się natychmiast, jeśli jedno z wywołań zwróci kod błędu dowolnego poziomu?
Zasadniczo chcę odpowiednik MSBuild ContinueOnError=false
.
batch-file
Josh Kodroff
źródło
źródło
Odpowiedzi:
Sprawdź, czy
errorlevel
wif
rachunku, a następnieexit /b
(opuścić b plik Atch tylko nie cały proces cmd.exe) do wartości innych niż 0.Jeśli chcesz, aby wartość poziomu błędu propagowała się poza plikiem wsadowym
ale jeśli to jest w środku
for
, staje się to trochę trudne. Potrzebujesz czegoś więcej:Edycja: Musisz sprawdzić błąd po każdym poleceniu. W partii cmd.exe / command.com nie ma globalnego typu „na błąd goto”. Zaktualizowałem również mój kod według CodeMonkey , chociaż nigdy nie spotkałem się z ujemnym poziomem błędu w żadnym z moich hackowań wsadowych na XP lub Vistę.
źródło
neq
) włączone / wyłączone nie ma znaczenia przy używaniu,if not errorlevel 1 exit /B
jak wyjaśniono w artykule pomocy technicznej Microsoft Korzystanie z operatorów przekierowywania poleceń i pomoc wyjściowa po uruchomieniuif /?
w oknie cmd. Bieżący poziom błędu (kod wyjścia) jest utrzymywany przy wychodzeniu z przetwarzania pliku wsadowego za pomocąexit /B
. Uwaga:exit
jeśli parametr/B
wymaga włączonych rozszerzeń poleceń, zobacz Gdzie wraca GOTO: EOF?Dodaj
|| goto :label
do każdej linii, a następnie zdefiniuj:label
.Na przykład utwórz ten plik .cmd:
Zobacz także pytanie dotyczące wychodzenia z podprogramu pliku wsadowego .
źródło
command || (SET ErrorLine=102 && goto :error)
||
stworzono. Być może nie w szczególności, ale „spróbuj, zrób to z błędem”, jak wspomniała Fowl. Moje pytanie brzmi: czy to działa dla wszystkich niezerowych kodów wyjścia? Tylko pozytywne?cmd /k exit -1 && echo success || echo fail
- drukowanie kończy się niepowodzeniem.command || exit /b %errorlevel%
Najkrótszy:
Jeśli potrzebujesz, możesz ustawić kod wyjścia:
Możesz także zalogować:
źródło
%ERRORLEVEL%
pozostaje nietknięty, kiedy dzwoniszexit /b
, więc kod błędu jest przekazywanyJedna drobna aktualizacja, należy zmienić sprawdzanie „jeśli poziom błędu 1” na następujące ...
Wynika to z faktu, że w XP można uzyskać liczby ujemne jako błędy. 0 = brak problemów, wszystko inne stanowi problem.
I pamiętaj o tym, jak DOS obsługuje testy „IF ERRORLEVEL”. Zwróci wartość true, jeśli liczba, którą sprawdzasz, jest tą liczbą lub wyższą, więc jeśli szukasz określonych numerów błędów, musisz zacząć od 255 i pracować dalej.
źródło
Oto program polyglot dla BASH i Windows CMD, który uruchamia serię poleceń i kończy działanie, jeśli któreś z nich się nie powiedzie:
W przeszłości używałem tego typu rzeczy do tworzenia skryptów ciągłej integracji na wielu platformach .
źródło
Wolę formę OR, ponieważ uważam, że są one najbardziej czytelne (w przeciwieństwie do opcji if po każdym poleceniu). Jednak naiwny sposób robienia tego
command || exit /b %ERRORLEVEL%
jest niewłaściwy .Wynika to z faktu, że partia rozszerza zmienne, gdy wiersz jest czytany po raz pierwszy, a nie kiedy są używane. Oznacza to, że jeśli
command
powyższy wiersz nie powiedzie się, plik wsadowy kończy się poprawnie, ale wychodzi z kodem powrotu 0, ponieważ taka była wartość%ERRORLEVEL%
na początku wiersza. Jest to oczywiście niepożądane w naszym skrypcie, dlatego musimy włączyć opóźnioną ekspansję :Ten fragment kodu wykona polecenia 1-4, a jeśli którykolwiek z nich zawiedzie, zakończy działanie z tym samym kodem wyjścia, co polecenie nieudane.
źródło
Nie zawsze możemy polegać na ERRORLEVEL, ponieważ wiele razy programy zewnętrzne lub skrypty wsadowe nie zwracają kodów wyjścia.
W takim przypadku możemy zastosować ogólne kontrole pod kątem takich awarii:
A jeśli program wypisze coś na konsolę, możemy to również sprawdzić.
źródło
Bez względu na to, jak próbowałem, poziom błędu zawsze pozostaje równy 0, nawet jeśli msbuild nie powiódł się. Więc zbudowałem swoje obejście:
Utwórz projekt i zapisz dziennik w Build.log
wyszukaj ciąg „0 Error” w dzienniku kompilacji, ustaw wynik na var
pobierz ostatni znak, który wskazuje, ile wierszy zawiera szukany ciąg
jeśli ciąg nie zostanie znaleziony, to błąd> 0, kompilacja nie powiodła się
To rozwiązanie zostało zainspirowane postem Mechaflasha na stronie Jak ustawić dane wyjściowe poleceń jako zmienne w pliku wsadowym
i https://ss64.com/nt/syntax-substring.html
źródło
for /f %%F in ('type build.log^|find /c /i "0 Error") do set result=%%F
. Uwaga:find "0 Error"
również znajdzie10 Errors
.źródło