If

Index

The IF command is used to provide conditional processing in batch programs.

Syntax:

IF condition command

IF NOT condition command

conditionIF will test for any of three conditions:
  1. string1==string2
  2. EXIST filename
  3. ERRORLEVEL x

IF tests condition and determines whether it is True or False.
For: IF condition command
   command is executed should condition be TRUE and skipped if FALSE.
For: IF NOT condition command
   command is executed should condition be FALSE and skipped if TRUE.

commandAny Dos command or executable program along with parameters and/or switches as required. Only one command can be specified.
To have more than one command dependent on the result of condition, it is necessary to branch to a label or second batch file and have the series there .

Although IF works in the same way for each of the above conditions, they are used in such different circumstances that they could almost be considered three separate commands:

1. Comparing Strings

Syntax:

IF [NOT] string1==string2 command

Notes:

  1. When comparing strings, note the use of the double equal signs!
    (Why it was considered that a single equal sign was insufficient is beyond me).

  2. String1 and/or string2 can be literal strings, batch variables (eg. %1), or environmental variables (eg. %windir%).

  3. The comparison is case sensitive
    ie.
    IF %windir% == C:\WINDOWS
    IF %windir% == c:\windows
    will be seen as True
    will be seen as False

  4. An error occurs if either string doesn't have at least one character. This can happen if one of the strings is a variable, and very likely will happen should the IF statement be contained within a loop in which the variable is changed in each cycle.
    To avoid this error arising it is typical to add dummy character(s) to both sides as:

    IF [NOT] "string1"=="string2" command
    or
    IF [NOT] string1x==string2x command

    Any character can be used as the dummy but it makes for simplicity to use the same character consistently. Indeed, the dummy can often be used as one of the trademarks of some batch file authors.

  5. Neither literal nor variable strings may contain = ; | < >.

  6. The parsing mechanism in IF seems to be able to handle embedded spaces in either string (literal or variable) but does not recognise quotes as special characters holding such strings together. Should the test result require command to be carried out, and string2 contains embedded spaces IF takes the second word as the command - typically resulting in a "Bad command" error message (see Examples below).
    I'm sure there is a good reason for IF's aversion to spaces - but it's a right nuisance!

Examples

  1. to determine whether all command line parameters have been processed in a loop containing a SHIFT command:
    	.....
    	:Step1
    	IF %1"==" GOTO Step2
    	SHIFT
    	COPY %1 a:
    	GOTO Step1
    	:Step2
    	.....

  2. Say the environmental variable "Name" could contain information in the form Fred Smith and "Name1" is Fred Smith (ie. with embedded spaces), then:
    CommandIf condition is TrueIf condition is False
    IF %Name%"==" GOTO CreateName
    OK - branch to label CreateName OK - command not executed
    IF NOT %Name%"==" GOTO Step2
    OK - command not executedOK - branch to label Part2
    IF %Name%"==%Name1%" GOTO Part2
    Error - "Bad command" OK - command not executed
    IF Fred Smith"==%Name%" GOTO Step2
    Error - "Bad command" OK - command not executed

2. Checking for the existence of a file (or directory)

Syntax:

IF [NOT] EXIST [path]filename command

filenameA file or Dos device

Notes:

  1. path must be included unless filename is in the current drive and directory. Entries in any Dos PATH statement are not recognised.

  2. [path]filename can use either short or long filename form (or a mixture) - but long names must be enclosed in quotes if they include spaces.

  3. Directories cannot be detected directly. However, the Dos devices (NUL, AUX, CON, COM1-4, LPT1-3, and PRN) are accessible from every directory and it follows that if directoryname\device exists, then so does the directory. Conversely, if directoryname\device doesn't exist, then nor does the directory.

    Although, theoretically, any of the above devices can be used for the test, every reference I have seen uses the NUL device. A quick test on my machine indicated that all devices were recognised except for LPT1/PRN which resulted in an error message:

    	General failure reading device
    	Abort, Retry, Fail?
    
    For reliability, NUL is probably the best choice.

  4. As well as the essential Dos devices (listed above) being accessible from any existing directory, any installed Dos devices (as recorded in an MEM /D display) are also so available and are recognised by IF [NOT] EXIST. Note that the names by which these devices are recognised is not the same as that of the device driver loaded in Config.sys and seem to be generally of the form:
    Device Driver filenameInstalled Device Name
    HIMEM.SYSXMSXXXX0
    EMM386.EXEEMMXXXX0
    Display.sysCON
    Dblbuff.sysDblBuff$
    Ifshlp.sysIFS$HLP$

Examples

  1. To copy a font to c:\windows\fonts from a CD-ROM (drive x:) only if it isn't already installed:
      IF NOT EXIST c:\windows\fonts\maxi.ttf COPY x:\maxi.ttf c:\windows\fonts

  2. To create the directory "tests" if it doesn't already exist:
      IF NOT EXIST c:\tests\NUL MD c:\tests

  3. To check that Himem.sys is currently installed:
      IF EXIST XMSXXXX0 echo Himem installed

Oddities

In Eric's "webspace" there is a description of distinctly bizarre behaviour when the output of IF EXIST filename is redirected to a file. Essentially:
  1. the file is created;
  2. Should the condition be True, when executed in a batch file, the entire next line (including prompt and [Enter]) is copied to the file. When working from the command line, the prompt along with any text entered from the keyboard up to and including [Enter] is put into the file. (Text entered is not displayed).
  3. Should the condition be False, a zero byte file is created.
I cannot see any use for this strange behaviour - but then I am not a batch file programmer!

3. Checking the exit code of a previous command

Syntax:

IF [NOT] ERRORLEVEL x command

Notes:

  1. When external Dos commands terminate, an exit code is returned to MS-Dos. For example, a value of 0 is typically used to indicate that a program was successfully executed. IF [NOT] ERRORLEVEL x tests the exit code returned by the last command and returns True when the exit code is greater than or equal to x and False when the exit code is less than x.

    Should, say, the exit code from the last command be 2 then:

    IF ERRORLEVEL 0 command0
    IF ERRORLEVEL 1 command1
    IF ERRORLEVEL 2 command2
    IF ERRORLEVEL 3 command3
    (True)
    (True)
    (True)
    (False)
    command0 is executed
    command1 is executed
    command2 is executed
    command3 is skipped
    IF NOT ERRORLEVEL 0 command0
    IF NOT ERRORLEVEL 1 command1
    IF NOT ERRORLEVEL 2 command2
    IF NOT ERRORLEVEL 3 command3
    (True)
    (True)
    (True)
    (False)
    command0 is skipped
    command1 is skipped
    command2 is skipped
    command3 is executed

  2. To associate a particular command with an exit code, it is necessary to use one of two constructions:
    1. Arrange the IF commands to test for exit codes in descending order.
      However, note that, unless commandx dictates otherwise, each IF line will be acted on in sequence. There are three ways to prevent valid, but irrelevant, commands being processed:
      1. Have the batch file branch to a label (using GOTO label);
      2. Irreversibly branch to a new batch file (by simply naming the file);
      3. Stopping the batch file with EXIT.

    2. Use a nested construction: IF ERRORLEVEL x IF NOT ERRORLEVEL x+1 commandx (where x is the exit code). The logic here is that commandx is only executed when x is True and any number larger than x is False. This structure is useful when each exit code is to result in a single command and a series of GOTOs would be cumbersome.

    Examples

    1. A series of IF commands is to follow a CHOICE command to display the key that was pressed in response to the prompt:
         CHOICE /C:ABC Press A, B, or C:
         IF ERRORLEVEL 1 IF NOT ERRORLEVEL 2 ECHO You pressed "A"
         IF ERRORLEVEL 3 IF NOT ERRORLEVEL 4 ECHO You pressed "C"
         IF ERRORLEVEL 2 IF NOT ERRORLEVEL 3 ECHO You pressed "B"
      
      Note: that the order of IF commands is not important.

    2. XCOPY is used in a batch file to back up any new or modified spreadsheet files. A series of IF commands are used to display various status message at the conclusion of the copying process.
         XCOPY d:\spreadsheets\*.* f:\spreadsheets\ /s/m
         IF ERRORLEVEL 3 GOTO Problems
         IF ERRORLEVEL 2 GOTO Cancel
         IF ERRORLEVEL 1 GOTO NoFiles
         IF ERRORLEVEL 0 GOTO OK
      
         :Problems
         ECHO You have problems!
         ECHO Modified/New files have not been backed up.
         GOTO end
      
         :Cancel
         ECHO Copying process terminated.
         GOTO end
      
         :NoFiles
         ECHO No files found to copy.
         GOTO continue
      
         :OK
         ECHO All new/modified files backed up.
         GOTO continue
      
         :continue
         ........
      
         :end
      
      Note: that the order of IF commands is most important!

    3. Oh yes, the (apparent) exception. To set an environmental variable according to a keypress (say), either of the above approaches will work just fine. However, simply to use
         CHOICE /C:ABC Press A, B, or C:
         IF ERRORLEVEL 3 SET key=C
         IF ERRORLEVEL 2 SET key=B
         IF ERRORLEVEL 1 SET key=A
      
      is tempting - but doesn't work! Instead the order should be reversed as:
         CHOICE /C:ABC Press A, B, or C:
         IF ERRORLEVEL 1 SET key=A
         IF ERRORLEVEL 2 SET key=B
         IF ERRORLEVEL 3 SET key=C
      

    File Details:

    Internal


If you should have any comments or suggestions,
please contact: Bob Watson
.
This page last revised:
October 17, 2000.