Rob van der Woude's Scripting Pages

Conditional execution

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 number2)
number1 GEQ number2 (true if number1 is greater than or equal to number2)
number1 LSS number2 (true if number1 is less than number2)
number1 LEQ number2 (true if number1 is less than or equal to number2)

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

The else keyword was introduced in CMD.EXE, and requires "grouping" with parentheses:

IF condition (
	command
) ELSE (
	command
)

or:

IF condition (command) ELSE (command)

or:

IF condition (command) ELSE command
Note: Whenever it says (command) with parentheses, you may insert multiple commands, as will be explained later on this page.

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
			)
		)
	)
)

 

Complex conditions

Both COMMAND.COM and CMD.EXE batch language lack and and or statements to combine conditions into a "complex condition".

The 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
	)
)

The 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

 

One-Liners

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:

 

One-Liners
Syntax Description Equivalent to
command1 & command2 Execute command2 after execution of command1 has finished command1
command2
command1 && command2 Execute command2 only if execution of command1 has finished successfully command1
IF %ErrorLevel% EQU 0 command2
command1 || command2 Execute command2 only if execution of command1 has finished unsuccessfully command1
IF %ErrorLevel% NEQ 0 command2

 

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.

 

Some examples:

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.

 

Complex One-Liners

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 command1 fails, command2 will still be executed, and if command2 succeeds, command3 will be executed, etc.
Error handling will only be triggered by failure of command2 .. command4

 

Warning Batch code can soon become unreadable using these one-liner constructions.
You may want to spread the code over multiple lines again:
(
    command1
    command2
) && (
    command3
) && (
    command4
) || (
    ECHO Error
)

Thanks Darin


page last modified: 2022-03-23; loaded in 0.0017 seconds