
Every scripting and programming language contains an error handler like Java contains try-catch
for error handling. In a Batch script, there is no direct way to do this, but we can create an error handler in the Batch script using a built-in variable of the Batch script name %ERRORLEVEL%
.
This article will show how we can create a Batch script to handle errors and failures. Also, we are going to some examples that make the topic easier.
Error Handling in Batch Script
When a command successfully executes, it always returns an EXIT CODE
that indicates whether the command successfully executed or failed to execute. So, to create an error handling in a Batch file, we can use that EXIT CODE
in our program.
You can follow below general format to create an error handler:
@Echo off
SomeCommand && (
ECHO Message for Success
) || (
ECHO Message for Failure or Error
)
We can also do that by checking the variable named %ERRORLEVEL%
. If the variable contains a value not equal to 0
, then there might be a problem or error when executing the command. To test the %ERRORLEVEL%
variable, you can follow the below example codes:
@ECHO off
Some Command Here !!!
IF %ERRORLEVEL% NEQ 0 (Echo Error found when running the command &Exit /b 1)
You must note that the keyword NEQ
means Not Equal. And the variable %ERRORLEVEL%
will only contain a non-zero value if there is a problem or error in the code.
An Example That Contains Errors
Below, we shared an example. We will run a Batch file named Your_file.bat
from a location.
We intentionally removed that file from the directory. So it’s an error command.
The code for our example will be:
@echo off
ECHO Running a Batch file
CD G:\BATCH\
CALL Your_file.bat
IF errorlevel 1 GOTO ERROR
ECHO The file run successfully.
GOTO EOF
:ERROR
ECHO The file didn't run successfully.
CMD /k
EXIT /b 1
:EOF
Now, as the file doesn’t exist in the directory, it will show an error, and you will get the below output when you run the code shared above.
Output:
Running a Batch file
The system cannot find the path specified.
'Your_file.bat' is not recognized as an internal or external command,
operable program or batch file.
The file didn't run successfully.
An Error-Free Code Example That Runs Successfully
In the example above, we made a mistake on the code intentionally to understand how the code works. If we correct it like below:
@echo off
ECHO Running a Batch file
CALL "G:\BATCH\Yourfile.bat"
IF errorlevel 1 GOTO ERROR
ECHO The file runs successfully.
GOTO EOF
:ERROR
ECHO The file didn't run successfully.
CMD /k
EXIT /b 1
:EOF
Then we will get an output like this:
Running a Batch file
This is from the first file
The file runs successfully.
Remember, all commands we discussed here are only for the Windows Command Prompt or CMD environment.
ПоделитьсяНашли опечатку?Пожалуйста, сообщите об этом — просто выделите ошибочное слово или фразу и нажмите Shift Enter.
|
Добавить комментарий |
I’m currently writing my first batch file for deploying an asp.net solution.
I’ve been Googling a bit for a general error handling approach and can’t find anything really useful.
Basically if any thing goes wrong I want to stop and print out what went wrong.
Can anyone give me any pointers?
John Saunders
161k26 gold badges247 silver badges397 bronze badges
asked Jul 22, 2009 at 9:15
I generally find the conditional command concatenation operators much more convenient than ERRORLEVEL.
yourCommand && (
echo yourCommand was successful
) || (
echo yourCommand failed
)
There is one complication you should be aware of. The error branch will fire if the last command in the success branch raises an error.
yourCommand && (
someCommandThatMayFail
) || (
echo This will fire if yourCommand or someCommandThatMayFail raises an error
)
The fix is to insert a harmless command that is guaranteed to succeed at the end of the success branch. I like to use (call )
, which does nothing except set the ERRORLEVEL to 0. There is a corollary (call)
that does nothing except set the ERRORLEVEL to 1.
yourCommand && (
someCommandThatMayFail
(call )
) || (
echo This can only fire if yourCommand raises an error
)
See Foolproof way to check for nonzero (error) return code in windows batch file for examples of the intricacies needed when using ERRORLEVEL to detect errors.
answered Jun 13, 2013 at 11:27
dbenhamdbenham
128k28 gold badges253 silver badges391 bronze badges
7
Using ERRORLEVEL when it’s available is the easiest option. However, if you’re calling an external program to perform some task, and it doesn’t return proper codes, you can pipe the output to ‘find’ and check the errorlevel from that.
c:\mypath\myexe.exe | find "ERROR" >nul2>nul
if not ERRORLEVEL 1 (
echo. Uh oh, something bad happened
exit /b 1
)
Or to give more info about what happened
c:\mypath\myexe.exe 2&1> myexe.log
find "Invalid File" "myexe.log" >nul2>nul && echo.Invalid File error in Myexe.exe && exit /b 1
find "Error 0x12345678" "myexe.log" >nul2>nul && echo.Myexe.exe was unable to contact server x && exit /b 1
answered Aug 27, 2013 at 16:55
1
Other than ERRORLEVEL, batch files have no error handling. You’d want to look at a more powerful scripting language. I’ve been moving code to PowerShell.
The ability to easily use .Net assemblies and methods was one of the major reasons I started with PowerShell. The improved error handling was another. The fact that Microsoft is now requiring all of its server programs (Exchange, SQL Server etc) to be PowerShell drivable was pure icing on the cake.
Right now, it looks like any time invested in learning and using PowerShell will be time well spent.
answered Jul 22, 2009 at 10:52
Brad BruceBrad Bruce
7,6483 gold badges40 silver badges60 bronze badges
3
A successful ping on your local network can be trapped using ERRORLEVEL
.
@ECHO OFF
PING 10.0.0.123
IF ERRORLEVEL 1 GOTO NOT-THERE
ECHO IP ADDRESS EXISTS
PAUSE
EXIT
:NOT-THERE
ECHO IP ADDRESS NOT NOT EXIST
PAUSE
EXIT
answered Jul 9, 2013 at 13:38
Rob DavisRob Davis
711 silver badge1 bronze badge
I guess this feature was added since the OP but for future reference errors that would output in the command window can be redirected to a file independent of the standard output
command 1> file — Write the standard output of command to file
command 2> file — Write the standard error of command to file
answered Feb 6, 2015 at 15:36
Python Unittest, Bat process Error Codes:
if __name__ == "__main__":
test_suite = unittest.TestSuite()
test_suite.addTest(RunTestCases("test_aggregationCount_001"))
runner = unittest.TextTestRunner()
result = runner.run(test_suite)
# result = unittest.TextTestRunner().run(test_suite)
if result.wasSuccessful():
print("############### Test Successful! ###############")
sys.exit(1)
else:
print("############### Test Failed! ###############")
sys.exit()
Bat codes:
@echo off
for /l %%a in (1,1,2) do (
testcase_test.py && (
echo Error found. Waiting here...
pause
) || (
echo This time of test is ok.
)
)
answered Sep 24, 2017 at 7:54
TonnyTonny
412 bronze badges
Its extremely easy!
Create a file that contains:
call <filename> // the file you made
cls
echo An error occured!
<Your commands>
pause
So now when you start it, it will launch your program as normal. But when anything goes wrong it exits and continues the script inside the first file. Now there you can put your own commands in.
answered Nov 17, 2016 at 19:51
BlazeLPBlazeLP
1351 silver badge8 bronze badges
0
1. Описание команды IF.
1.1. Формат командной строки:
C:\ IF [NOT] ERRORLEVEL число команда C:\ IF [NOT] строка1==строка2 команда C:\ IF [NOT] EXIST имя_файла команда
1.2. Параметры:
- NOT — Указывает, что Windows должна выполнить эту команду, только если условие является ложным.
- ERRORLEVEL число — Условие является истинным, если код возврата последней выполненной программы не меньше указанного числа.
- строка1==строка2 — Условие является истинным, если указанные строки совпадают.
- EXIST имя_файла — Условие является истинным, если файл с указанным именем существует.
- команда — Задает команду, выполняемую при истинности условия. За этой командой может следовать ключевое слово ELSE. В случае, если указанное условие ложно, будет выполнена команда, находящаяся после слова ELSE.
1.3. Предложение ELSE должно располагаться в той же строке, что и команда, следующая за ключевым словом IF.
Например:
IF EXIST имя_файла. (
del имя_файла.
) ELSE (
echo имя_файла. missing.
)
1.4. Следующий пример содержит ОШИБКУ, поскольку команда del должна заканчиваться переходом на новую строку:
C:\ IF EXIST имя_файла. del имя_файла. ELSE echo имя_файла. Missing
1.5. Следующий пример также содержит ОШИБКУ, поскольку команда ELSE должна располагаться в той же строке, что и команда, следующая за IF:
IF EXIST имя_файла. del имя_файла.
ELSE echo имя_файла. missing
1.6. Вот правильный пример, где все команды расположены в одной строке:
C:\ IF EXIST имя_файла. (del имя_файла.) ELSE echo имя_файла. Missing
1.7. Изменение команды IF при включении расширенной обработки команд:
C:\ IF [/I] строка1 оператор_сравнения строка2 команда C:\ IF CMDEXTVERSION число команда C:\ IF DEFINED переменная команда
где оператор_сравнения принимает следующие значения:
- EQU — равно
- NEQ — не равно
- LSS — меньше
- LEQ — меньше или равно
- GTR — больше
- GEQ — больше или равно
а ключ /I, если он указан, задает сравнение текстовых строк без учета регистра.
Ключ /I можно также использовать и в форме строка1==строка2 команды IF. Сравнения проводятся по общему типу данных, так что если строки 1 и 2 содержат только цифры, то обе строки преобразуются в числа, после чего выполняется сравнение чисел.
Условие CMDEXTVERSION применяется подобно условию ERRORLEVEL, но значение сравнивается с внутренним номером версии текущей реализации расширенной обработки команд. Первая версия имеет номер 1. Номер версии будет увеличиваться на единицу при каждом добавлении существенных возможностей расширенной обработки команд. Если расширенная обработка команд отключена, условие CMDEXTVERSION никогда не бывает истинно.
Условие DEFINED применяется подобно условию EXIST, но принимает в качестве аргумента имя переменной среды и возвращает истинное значение, если эта переменная определена.
1.8. Строка %ERRORLEVEL% будет развернута в строковое представление текущего значения кода ошибки ERRORLEVEL, за исключением ситуации, когда уже имеется переменная среды с именем ERRORLEVEL; в подобном случае подставляется значение этой переменной.
Например, с помощью данной строки можно выполнить следующее:
goto answer%ERRORLEVEL% :answer0 echo Получен код возврата 0 :answer1 echo Получен код возврата 1
1.9. Допускается и применение описанных выше операторов числового сравнения:
C:\ IF %ERRORLEVEL% LEQ 1 goto okay
1.10. Строка %CMDCMDLINE% будет развернута в исходную командную строку, переданную CMD.EXE до любой обработки, за исключением ситуации, когда уже определена переменная среды с именем CMDCMDLINE; в подобном случае подставляется значение этой переменной.
1.11. Строка %CMDEXTVERSION% будет развернута в строку, представляющую собой текущее значение CMDEXTVERSION, за исключением ситуации, когда уже имеется переменная среды с именем CMDEXTVERSION; в подобном случае подставляется значение этой переменной.
2. Примеры использования.
2.1. Создание пустого файла, имя которого задается параметром командной строки.
Если параметр командной строки не задан, то пользователю выдается сообщение об ошибке.
@echo off REM Проверить наличие имени файла, задаваемого в качестве параметра %1 REM Если параметр %1 пустой – переход на метку error if "%1" EQU "" goto error REM Если параметр задан, создаем пустой файл, копированием из устройства nul copy nul "%1" exit :error ECHO File name required ! Must be - %~n0 filename.ext :exit
2.2. Командный файл, выполняющий опрос командой ping сетевых адресов в заданном диапазоне ( 192.168.1.1 – 192.168.1.254 ).
Команда ping формирует значение переменной ERRORLEVEL равное нулю, если верно заданы параметры командной строки. То есть, определить доступность пингуемого IP-адреса методом анализа кода возврата ping не получится, поскольку он будет нулевым, независимо от того, отвечает ли пингуемое устройство, или нет. Поэтому, для решения данной задачи необходимо определить характерный признак, который присутствует в выводимых результатах только в том случае, когда пингуемое устройство доступно. Таким признаком может быть наличие строки символов «TTL» в выводе команды ping. Для определения признака можно использовать команду find в цепочке с командой ping.
Примеры вывода для отвечающего и не отвечающего узлов:
Ответ от 192.168.1.1: число байт=32 время=1мс TTL=64 - если устройство с данным IP-адресом доступно;
Превышен интервал ожидания для запроса. - если устройство не отвечает;
Команда find /I «TTL» возвращает код ERRORLEVEL равный 0, если строка «TTL» присутствует в результате выполнения ping. Ключ /I имеет смысл использовать, чтобы результат не зависил от того, строчные или заглавные символы составляют строку «ttl«.
Результат работы командного файла записывается в текстовый файл iplist.txt
@ECHO OFF REM Постоянная часть IP-адреса set IPTMP=192.168.1. REM Количество пингуемых узлов set N=254 rem С какого адреса начать - начальное значение " хвоста " IP- адреса X.X.X.IPMIN set /A IPMIN=1 ECHO %DATE% Опрос пингом %N% адресов начиная с %IPTMP%%IPMIN% >> iplist.txt rem M0 - метка для организации цикла :M0 rem Переменная IPFULL - полное значение текущего IP-адреса set IPFULL=%IPTMP%%IPMIN% rem Если " хвост "больше N – перейти к завершению работы IF %IPMIN% GTR %N% GOTO ENDJOB ping -n 1 %IPFULL% | find /I "TTL" if %ERRORLEVEL%==0 Echo %IPFULL% >> iplist.txt rem Сформируем следующий IP-адрес set /A IPMIN=%IPMIN% + 1 rem Перейдем на выполнение следующего шага GOTO M0 rem Завершение работы :endjob exit
Существуют некоторые особенности реализации командного интерпретатора CMD.EXE, которые необходимо учитывать при обработке значений переменных внутри циклов IF и FOR. Использование значений переменных внутри скобок, требует изменения стандартного режима интерпретации командного процессора. Разработчиками предусмотрена возможность запуска CMD.EXE с параметром /V:ON, что включает разрешение отложенного расширения переменных среды с применением символа восклицательного знака (!) в качестве разделителя. То есть, параметр /V:ON разрешает использовать !var! в качестве значения переменной var во время выполнения внутри циклов команд FOR и IF. Но на практике чаще используется возможность локального включения данного режима внутри командного файла специальной директивой:
Setlocal EnableDelayedExpansion
После чего, можно обрабатывать принимаемые переменными значения внутри цикла, используя вместо знаков процента восклицательные знаки:
FOR … ( IF !ERRORLEVEL!==0 вместо %ERRORLEVEL%==0 … )
В русскоязычной справке команды IF имеется ошибка, которая много лет переходит из версии в версию — вместо оператора EQU — равно, указано EQL — равно
- Overview
- Part 1 – Getting Started
- Part 2 – Variables
- Part 3 – Return Codes
- Part 4 – stdin, stdout, stderr
- Part 5 – If/Then Conditionals
- Part 6 – Loops
- Part 7 – Functions
- Part 8 – Parsing Input
- Part 9 – Logging
- Part 10 – Advanced Tricks
Today we’ll cover return codes as the right way to communicate the outcome of your script’s execution to the world. Sadly, even
skilled Windows programmers overlook the importance of return codes.
Return Code Conventions
By convention, command line execution should return zero when execution succeeds and non-zero when execution fails. Warning messages
typically don’t effect the return code. What matters is did the script work or not?
Checking Return Codes In Your Script Commands
The environmental variable %ERRORLEVEL%
contains the return code of the last executed program or script. A very helpful feature is
the built-in DOS commands like ECHO
, IF
, and SET
will preserve the existing value of %ERRORLEVEL%
.
The conventional technique to check for a non-zero return code using the NEQ
(Not-Equal-To) operator of the IF
command:
IF %ERRORLEVEL% NEQ 0 (
REM do something here to address the error
)
Another common technique is:
IF ERRORLEVEL 1 (
REM do something here to address the error
)
The ERRORLEVEL 1
statement is true when the return code is any number equal to or greater than 1. However, I don’t use this technique because
programs can return negative numbers as well as positive numbers. Most programs rarely document every possible return code, so I’d rather explicity
check for non-zero with the NEQ 0
style than assuming return codes will be 1 or greater on error.
You may also want to check for specific error codes. For example, you can test that an executable program or script is in your PATH by simply
calling the program and checking for return code 9009.
SomeFile.exe
IF %ERRORLEVEL% EQU 9009 (
ECHO error - SomeFile.exe not found in your PATH
)
It’s hard to know this stuff upfront – I generally just use trial and error to figure out the best way to check the return code of the program or
script I’m calling. Remember, this is duct tape programming. It isn’t always pretty, but, it gets the job done.
Conditional Execution Using the Return Code
There’s a super cool shorthand you can use to execute a second command based on the success or failure of a command. The first program/script must
conform to the convention of returning 0 on success and non-0 on failure for this to work.
To execute a follow-on command after sucess, we use the &&
operator:
SomeCommand.exe && ECHO SomeCommand.exe succeeded!
To execute a follow-on command after failure, we use the ||
operator:
SomeCommand.exe || ECHO SomeCommand.exe failed with return code %ERRORLEVEL%
I use this technique heavily to halt a script when any error is encountered. By default, the command processor will continue executing
when an error is raised. You have to code for halting on error.
A very simple way to halt on error is to use the EXIT
command with the /B
switch (to exit the current batch script context, and not the command
prompt process). We also pass a specific non-zero return code from the failed command to inform the caller of our script about the failure.
SomeCommand.exe || EXIT /B 1
A simliar technique uses the implicit GOTO label called :EOF
(End-Of-File). Jumping to EOF in this way will exit your current script with
the return code of 1.
SomeCommand.exe || GOTO :EOF
Tips and Tricks for Return Codes
I recommend sticking to zero for success and return codes that are positive values for DOS batch files. The positive values are a good idea
because other callers may use the IF ERRORLEVEL 1
syntax to check your script.
I also recommend documenting your possible return codes with easy to read SET
statements at the top of your script file, like this:
SET /A ERROR_HELP_SCREEN=1
SET /A ERROR_FILE_NOT_FOUND=2
Note that I break my own convention here and use uppercase variable names – I do this to denote that the variable is constant and should not
be modified elsewhere. Too bad DOS doesn’t support constant values like Unix/Linux shells.
Some Final Polish
One small piece of polish I like is using return codes that are a power of 2.
SET /A ERROR_HELP_SCREEN=1
SET /A ERROR_FILE_NOT_FOUND=2
SET /A ERROR_FILE_READ_ONLY=4
SET /A ERROR_UNKNOWN=8
This gives me the flexibility to bitwise OR multiple error numbers together if I want to record numerous problems in one error code.
This is rare for scripts intended for interactive use, but, it can be super helpful when writing scripts you support but you don’t
have access to the target systems.
@ECHO OFF
SETLOCAL ENABLEEXTENSIONS
SET /A errno=0
SET /A ERROR_HELP_SCREEN=1
SET /A ERROR_SOMECOMMAND_NOT_FOUND=2
SET /A ERROR_OTHERCOMMAND_FAILED=4
SomeCommand.exe
IF %ERRORLEVEL% NEQ 0 SET /A errno^|=%ERROR_SOMECOMMAND_NOT_FOUND%
OtherCommand.exe
IF %ERRORLEVEL% NEQ 0 (
SET /A errno^|=%ERROR_OTHERCOMMAND_FAILED%
)
EXIT /B %errno%
If both SomeCommand.exe and OtherCommand.exe fail, the return code will be the bitwise combination of 0x1 and 0x2, or decimal 3. This return code tells
me that both errors were raised. Even better, I can repeatedly call the bitwise OR with the same error code and still interpret which errors were
raised.
<< Part 2 – Variables
Part 4 – stdin, stdout, stderr >>