Как заставить пакетный файл завершиться при возникновении ошибки?



У меня есть пакетный файл, который вызывает один и тот же исполняемый файл снова и снова с разными параметрами. Как заставить его немедленно завершиться, если один из вызовов возвращает код ошибки любого уровня?



в принципе, я хочу, что эквивалентно .

625   10  

10 ответов:

Регистрация errorlevel на if заявление, а потом exit /b (выход bтолько файл atch, а не весь cmd.exe process) для значений, отличных от 0.

same-executable-over-and-over.exe /with different "parameters"
if %errorlevel% neq 0 exit /b %errorlevel%

если вы хотите, чтобы значение errorlevel распространялось за пределы вашего пакетного файла

if %errorlevel% neq 0 exit /b %errorlevel%

но если это внутри for это становится немного сложнее. Вам понадобится что-то вроде:

setlocal enabledelayedexpansion
for %%f in (C:\Windows\*) do (
    same-executable-over-and-over.exe /with different "parameters"
    if !errorlevel! neq 0 exit /b !errorlevel!
)

Edit: вы должны проверить ошибку после каждой команды. В пакете cmd.exe/command.com нет глобального типа конструкции "on error goto". Я также обновил свой код на CodeMonkey, хотя я никогда не сталкивался с отрицательным уровнем ошибок в любом из моих пакетных взломов на XP или Vista.

добавить || goto :label к каждой строке, а затем определить :label.

например, создайте это .файл cmd:

@echo off

echo Starting very complicated batch file...
ping -invalid-arg || goto :error
echo OH noes, this shouldn't have succeeded.
goto :EOF

:error
echo Failed with error #%errorlevel%.
exit /b %errorlevel%

см. также вопрос о выходе из подпрограммы пакетного файла.

минимальные:

command || exit /b

Если вам нужно, вы можете установить код на выходе:

command || exit /b 666

и вы также можете войти:

command || echo ERROR && exit /b

одно незначительное обновление, вы должны изменить проверки для "Если errorlevel 1" на следующее...

IF %ERRORLEVEL% NEQ 0 

Это потому, что на XP вы можете получить отрицательные числа в качестве ошибок. 0 = Нет проблем, все остальное-это проблема.

и имейте в виду, как DOS обрабатывает тесты "IF ERRORLEVEL". Он вернет true, если число, которое вы проверяете, является этим числом или выше, поэтому, если вы ищете конкретные номера ошибок, вам нужно начать с 255 и работать вниз.

здесь полиглот программа для BASH и Windows CMD, который выполняет ряд команд и завершает работу, если какой-либо из них не удается:

#!/bin/bash 2> nul

:; set -o errexit
:; function goto() { return $?; }

command 1 || goto :error

command 2 || goto :error

command 3 || goto :error

:error

:; exit 0
exit /b 0

:error
exit /b %errorlevel%

я использовал этот тип вещи в прошлом для нескольких платформ непрерывная интеграция сценарий.

Я предпочитаю или форму команды, так как я нахожу их наиболее читаемыми (как против того, чтобы иметь if после каждой команды). Однако, наивный путь делая это,command || exit /b %ERRORLEVEL% и неправильно.

это потому, что пакет расширяет переменные при первом чтении строки, а не чем когда они используются. Это означает, что если command в строке выше сбой, пакетный файл завершает работу правильно, но он завершается с кодом возврата 0, потому что значение %ERRORLEVEL% был в начало линия. Очевидно, что это нежелательно в нашем скрипте, поэтому мы должны включить отложенная экспансия, например:

SETLOCAL EnableDelayedExpansion

command-1 || exit /b !ERRORLEVEL!
command-2 || exit /b !ERRORLEVEL!
command-3 || exit /b !ERRORLEVEL!
command-4 || exit /b !ERRORLEVEL!

этот фрагмент будет выполнять команды 1-4, и если какой-либо из них не удастся, он будет выход с тем же кодом выхода, так как не выполнила.

мы не всегда можем зависеть от ERRORLEVEL, потому что много раз внешние программы или пакетные сценарии не возвращают коды выхода.

в этом случае мы можем использовать общие проверки для сбоев, как это:

IF EXIST %outfile% (DEL /F %outfile%)
CALL some_script.bat -o %outfile%
IF NOT EXIST %outfile%  (ECHO ERROR & EXIT /b)

и если программа выводит что-то на консоль, мы также можем это проверить.

some_program.exe 2>&1 | FIND "error message here" && (ECHO ERROR & EXIT /b)
some_program.exe 2>&1 | FIND "Done processing." || (ECHO ERROR & EXIT /b)

независимо от того, как я пытался, errorlevel всегда остается 0, даже если msbuild не удалось. Поэтому я построил свой обходной путь:

построить проект и сохранить журнал для сборки.журнал

SET Build_Opt=/flp:summary;logfile=Build.log;append=true

msbuild "myproj.csproj" /t:rebuild /p:Configuration=release /fl %Build_Opt%

поиск строки "0 Error" в журнале сборки, установите результат в var

FOR /F "tokens=* USEBACKQ" %%F IN (`find /c /i "0 Error" Build.log`) DO (
    SET var=%%F
)
echo %var%

получить последний символ, который указывает, сколько строк содержит строку поиска

set result=%var:~-1%

echo "%result%"

если строка не найдена, то error > 0, build failed

if "%result%"=="0" ( echo "build failed" )

это решение было вдохновленный сообщением Mechaflash в как установить команды, выводимые в виде переменной в пакетном файле

и https://ss64.com/nt/syntax-substring.html

просто использовать ERRORLEVEL для достижения желаемого результата. Есть две переменные в ERRORLEVEL команда, которая определит, если процесс не удалось или успешно, эти переменные ERRORLEVEL 0 и ERRORLEVEL 1 (1 для fail, 0 для pass). Вот пример того, как это будет использоваться в пакетном файле:

echo off
cls
ping localhost 
errorlevel 0 goto :good
errorlevel 1 goto :bad

:good
cls
echo Good!
echo[
pause
exit

:bad
cls
echo Bad!
echo[
pause
exit

вот ссылка с дополнительной информацией, если вам это нужно: Errorlevels

@echo off

set startbuild=%TIME%

C:\WINDOWS\Microsoft.NET\Framework\v3.5\msbuild.exe c:\link.xml /flp1:logfile=c:\link\errors.log;errorsonly /flp2:logfile=c:\link\warnings.log;warningsonly || goto :error

copy c:\app_offline.htm "\lawpccnweb01\d$\websites\OperationsLinkWeb\app_offline.htm"

del \lawpccnweb01\d$\websites\OperationsLinkWeb\bin\ /Q

echo Start Copy: %TIME%

set copystart=%TIME%

xcopy C:\link\_PublishedWebsites\OperationsLink \lawpccnweb01\d$\websites\OperationsLinkWeb\ /s /y /d

del \lawpccnweb01\d$\websites\OperationsLinkWeb\app_offline.htm

echo Started Build: %startbuild%
echo Started Copy: %copystart%
echo Finished Copy: %TIME%

c:\link\warnings.log

:error

c:\link\errors.log

Comments

    Ничего не найдено.