Like any scripting or programming language, the batch language provides conditional execution, i.e.
if condition then command [ else command ]
In DOS (COMMAND.COM),
condition can be:
[NOT] ERRORLEVEL number [/I] [NOT] string1==string2 [NOT] EXIST filename
In NT (CMD.EXE, Windows NT 4 and later) numerical comparisons were added:
number1 EQU number2 (true if numbers are equal)
number1 NEQ number2 (true if numbers are not equal
number1 GTR number2 (true if
number1 is greater than
number1 GEQ number2 (true if
number1 is greater than or equal to
number1 LSS number2 (true if
number1 is less than
number1 LEQ number2 (true if
number1 is less than or equal to
Comparisons are really basic, i.e.
IF %a% GTR %b% will work,
IF %a% + %b% GTR %c% will not.
In the batch language, the keyword
then is not used:
IF condition command
else keyword was introduced in CMD.EXE, and requires "grouping" with parentheses:
IF condition ( command ) ELSE ( command )
IF condition (command) ELSE (command)
IF condition (command) ELSE command
|Note:||Whenever it says
The latter is quite interesting, as it allows
ELSE IF constructions:
IF condition1 ( command1 ) ELSE IF condition2 ( command2 ) ELSE IF condition3 ( command3 ) ELSE IF condition4 ( command4 ) ELSE ( command_none )
Much better than:
IF condition1 ( command1 ) ELSE ( IF condition2 ( command2 ) ELSE ( IF condition3 ( command3 ) ELSE ( IF condition4 ( command4 ) ELSE ( command_none ) ) ) )
Both COMMAND.COM and CMD.EXE batch language lack
or statements to combine conditions into a "complex condition".
and statement is fairly easy to emulate in COMMAND.COM and CMD.EXE alike:
IF condition1 IF condition2 ECHO Condition1 AND Condition2 were both met
or (CMD.EXE only):
IF condition1 ( IF condition2 ( ECHO Condition1 AND Condition2 were both met ) )
or functionality requires more code:
SET AtLeastOneConditionMet=false IF condition1 SET AtLeastOneConditionMet=true IF condition2 SET AtLeastOneConditionMet=true IF "%AtLeastOneConditionMet%"=="true" ECHO Condition1 OR condition2 OR both were met
Most program executables set an ErrorLevel stating success or failure of their execution.
This allows for error handling by using
IF ERRORLEVEL 1 ... or
IF %ErrorLevel% NEQ 0 ..., e.g.:
DIR somefolder IF %ErrorLevel% EQU 0 ( ECHO Directory "somefolder" exists ) ELSE ( ECHO Directory "somefolder" does not exist )
CMD.EXE for both OS/2 and Windows NT 4 and later offer a way to create "one-liners", making the error handling code a bit simpler:
||Execute command2 after execution of command1 has finished||
||Execute command2 only if execution of command1 has finished successfully||
||Execute command2 only if execution of command1 has finished unsuccessfully||
|Note:||Conditional execution based on success or failure of a previous command will only work if that previous command sets an ErrorLevel based on its success or failure.|
FORMAT A: /Q && COPY C:\DATA\*.* A:
will copy all files from C:\DATA to diskette IF and ONLY IF the format succeeds.
XCOPY C:\*.* D:\ /S 2>&1> NUL || ECHO Something terrible happened
will display your own custom error message if XCOPY fails.
What if we want a number of commands to be executed, and abort if any of these commands fails?
command1 IF %ErrorLevel% EQU 0 ( command2 IF %ErrorLevel% EQU 0 ( command3 IF %ErrorLevel% NEQ 0 ( ECHO Error 3 ) ) ELSE ( ECHO Error 2 ) ) ELSE ( ECHO Error 1 )
If we are not interested in the distinction between errors 1,2 or 3, we can simplify the code:
command1 && command2 && command3 || ECHO Error
For simple commands this will work, but sometimes I got unexpected results in constructions like these.
Darin Schnetzler found a more reliable way to write these one-liners:
(command1) && (command2) && (command3) || (ECHO Error)
If any command in the "chain" fails, the rest will be skipped and the error handling (in this case
ECHO Error) will be executed.
The parentheses allow (sub)grouping of commands too:
(command1 & command2) && (command3) && (command4) || (ECHO Error)
In this case, if
command2 will still be executed, and if
command3 will be executed, etc.
Error handling will only be triggered by failure of
|Warning||Batch code can soon become unreadable using these one-liner constructions.
You may want to spread the code over multiple lines again:
page last modified: 2022-03-23