Как сделать пакетный файл завершенным после возникновения ошибки?
У меня есть пакетный файл, который много раз вызывает один и тот же исполняемый файл с разными параметрами. Как заставить его немедленно прекратить работу, если один из вызовов возвращает код ошибки любого уровня?
В принципе, я хочу эквивалент MSBuild ContinueOnError=false
.
Ответы
Ответ 1
Проверьте errorlevel
в операторе if
, а затем exit /b
(закройте только файл b, а не весь процесс cmd.exe) для значений, отличных от 0.
same-executable-over-and-over.exe /with different "parameters"
if %errorlevel% neq 0 exit /b %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!
)
Изменить: Вы должны проверить ошибку после каждой команды. В cmd.exe/command.com не существует глобального типа "с ошибкой goto". Я также обновил свой код в CodeMonkey, хотя я никогда не сталкивался с отрицательным уровнем ошибок в любом из моих пакетных взломов на XP или Vista.
Ответ 2
Добавьте || 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%
См. также вопрос об окончании подпрограммы пакетного файла.
Ответ 3
Самый короткий:
command || exit /b
Если вам нужно, вы можете установить код выхода:
command || exit /b 666
И вы также можете зарегистрировать:
command || echo ERROR && exit /b
Ответ 4
Одно небольшое обновление, вы должны изменить проверки на "if errorlevel 1" на следующее...
IF %ERRORLEVEL% NEQ 0
Это потому, что на XP вы можете получить отрицательные числа как ошибки. 0 = нет проблем, что-то еще проблема.
И помните, как DOS обрабатывает тесты "IF ERRORLEVEL". Он вернет true, если число, которое вы проверяете, - это номер или выше, поэтому, если вы ищете конкретные номера ошибок, вам нужно начать с 255 и работать вниз.
Ответ 5
Вот для 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%
Я использовал этот тип в прошлом для множественной платформы непрерывная интеграция script.
Ответ 6
Независимо от того, как я пытался, уровень ошибок всегда остается 0, даже если msbuild не удалось. Поэтому я построил свое решение:
Создайте проект и сохраните журнал в Build.log
SET Build_Opt=/flp:summary;logfile=Build.log;append=true
msbuild "myproj.csproj" /t:rebuild /p:Configuration=release /fl %Build_Opt%
найдите строку "0 Ошибка" в журнале построения, установите результат в 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%"
если строка не найдена, тогда ошибкa > 0, ошибка сборки
if "%result%"=="0" ( echo "build failed" )
Это решение было вдохновлено сообщением Мечафлаша в Как установить команды в качестве переменной в пакетном файле
и https://ss64.com/nt/syntax-substring.html
Ответ 7
Мы не всегда можем зависеть от 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)
Ответ 8
Просто используйте ERRORLEVEL
для достижения желаемого результата. В команде ERRORLEVEL
есть две переменные, которые определяли бы, был ли процесс неудачным или преуспел, эти переменные ERRORLEVEL 0
и ERRORLEVEL 1
(1 для отказа, 0 для прохода). Вот пример того, как это будет использоваться в пакетном файле:
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
Вот ссылка с дополнительной информацией, если вам это нужно: Уровни ошибок
Ответ 9
@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