Conditional Expressions

The commands DO (when used with the UNTIL or WHILE keyword), IF, IFF/ELSEIFF, and the variable function @IF evaluate a conditional expression, and perform a different action based on whether or not the expression is TRUE. The SWITCH command tests pairs of values for equality. Most of the examples below use the IF command, but conditional expressions could be used in the other cases above as well.


A conditional expression can be one of the following, as described below:


Onesteprelational expression
Onestepstatus test
Onesteplogical expression


Relational Expression


A relational expression compares two character strings, using one of the relational operators in the table below. Each of these two character strings can contain literal text, environment and internal variables, and variable functions, including user defined ones, in any combination. Note that double quotes are significant.


Numeric and String Comparison


When comparing the two character strings, either a numeric or a string comparison will be used. A numeric comparison treats the strings as numeric values and tests them arithmetically. A string comparison treats the strings as text. The parser uses the rules described for the @NUMERIC function to determine whether or not the strings are numeric, and only if both are numeric is a numeric comparison performed. If either value is non-numeric, a string comparison is used. To force a string comparison when both values may be numeric, use double quotes around the values you are testing, as shown below. Because the quote mark is not a numeric character, string comparison is performed. Numeric comparison cannot be forced. To compare hexadecimal numbers numerically, you must convert them to decimal numbers using @CONVERT. This is not necessary if both are the same length - string comparison and numeric comparison yield the same result.


The example below demonstrates the difference between numeric and string comparisons, as shown in the table below. Numerically, 2 is smaller, but as a string it is "larger" because its first digit is larger than the first digit of 19. So the first of these conditions will be true, and the second will be false:




comparison type

2  lt  19



"2" lt "19"




Relational Expression Formats


The format of a relational expression is one of


num1 relational operator num2

string1 relational operator string2


Note: The correct syntax requires a space both before and after operator to separate it from its operands. Commonly seen constructs such as %a==b may or may not work depending on the specific parameters, but they are never recommended.


Relational Operators



numeric comparison: expression is true if

string comparison: expression is true if, when ignoring character case:

EQ or ==

num1 equals num2

string1 equals string2

NE or !=

num1 does not equal num2

string1 does not equal string2


num1 is less than num2

string1 alphabetically precedes string2


num1 is less than or is equal to num2

string1 alphabetically precedes or is equal to string2


num1 is greater than or is equal to num2

string1 alphabetically succeeds or is equal to string2


num1 is greater than num2

string1 alphabetically succeeds string2


tested as strings è

string1 is identical to string2, including character case


regular expression test

string1 matches the regular expression in string2


regular expression test

string1 doesn't match the regular expression in string2


Case differences are ignored in string comparisons (except by EQC). If two strings begin with the same text but one is shorter, the shorter string is considered to precede (be less than) the longer one. For example, "a" is less than "abc", and "hello_there" is greater than "hello".


When you compare text strings, you may need to enclose the parameters in double quotes in order to avoid syntax errors which can occur if one of the parameter values is empty (e.g., due to an environment variable which has never been assigned a value). This technique will not work for numeric comparisons, as the quotes will force a string comparison, so with numeric tests you must be sure that all variables are assigned values before the test is done.


In order to maintain compatibility with CMD, TCC recognizes the following additional names for conditions:

















Internal variables and variable functions are very powerful when combined with string and numeric comparisons. They allow you to test the state of your system, the characteristics of a file, date and time information, or the result of a calculation. You may want to review the variables and variable functions when determining the best way to set up a condition test.


Status Test


These conditions test operating system, file system or TCC status. In addition to the tests below, there are many internal variables and variable functions which allow you to test the status of many other parts of the system.


In the descriptions below of the various status tests, the status tests are true if and only if the specified condition is true.


DEFINED variable

If variable exists in the environment, the expression is true. This is equivalent to testing whether or not variable is nonempty.

Note: GOSUB variables, array variables, and internal variables do not exist in the environment, so they always fail the DEFINED test.

ERRORLEVEL [relational operator] n

This test retrieves the exit code of the preceding external program. By convention, programs return an exit code of 0 when they are successful and a non-zero number to indicate an error. The relational operator may be any of those listed above (e.g., EQ, GT). If no operator is specified, the default is GE. The comparison is done numerically.

Not all programs return an explicit exit code. For programs which do not, the behavior of ERRORLEVEL is undefined.

EXIST filename

If filename matches a file which exists, the expression is true. You can use wildcards in filename, in which case the expression is true if any file matching the wildcard name exists. filename may include an absolute or relative path.

WARNING: In Windows the expression will be true if there is either a file or a directory named filename. Use ISFILE or ISDIR instead.

The special filename NUL is commonly used in CMD batch files to test the existence of a directory. The expression exist xxx\NUL is true only if xxx is a directory.

ISALIAS aliasname

If aliasname is defined as an alias, the expression is true.

ISAPP appname

If appname matches the name of an application which is currently running, the expression is true. To match a specific application, you must enter the full pathname of the application. Partial names and wildcards will yield undependable results. Both the short and long filename forms of the name will be checked (see LFN File Searches for details on the correspondence between short and long filenames).

This test may require DEBUG privilege.

ISDIR path



If the directory specified by path exists, the expression is true. Path may be either absolute or relative. DIREXIST may be used as a synonym for ISDIR.

ISFILE filename

If filename matches a file which exists, the expression is true. You can use wildcards in the filename, in which case the expression is true if any file matching the wildcard name exists. ISFILE matches only files, not directories.


If the user-defined function name is loaded, the expression is true.


If command is an active internal command, the expression is true. Commands can be activated and deactivated with the SETDOS /I command.


If label exists in the current batch file, the expression is true. Labels may be one or more words long. Note that this test has nothing to do with disk partition labels.


If name is a plugin variable, function, or command, the expression is true.

ISWINDOW "title"

If a window which matches the title exists, the expression is true. double quotes must be used around the title, which may contain wildcards and extended wildcards.


ISHUNG "title"

If the specified window is not responding, the expression is true.


PLUGIN module

If the plugin module is loaded, the expression is true. Do not include an extension (i.e., ".dll"), for the module name.


Logical Expressions


A logical expression is one of the following:


 Onestep        a relational expression

 Onestep        a status test

 Onestep        the unary logical operator NOT (or !) followed by a logical expression

 Onestep        two logical expressions connected by a binary logical operator


Logical operators





value is TRUE if



NOT cond

cond is FALSE.



cond1 .AND. cond2

both cond1 and cond2 are TRUE.



cond1 .OR. cond2

at least one of cond1 and cond2 is TRUE.



cond1 .XOR. cond2

one of cond1 and cond2 is TRUE, and the other one is FALSE.


This example runs a program called DATALOAD if today is Monday or Tuesday (enter this on one line):


if "%_dow" == "Mon" .or. "%_dow" == "Tue" dataload


Test conditions are always scanned from left to right -- there is no implied order of precedence, as there is in some programming languages. You can, however, force a specific order of testing by grouping conditions with parentheses, for example (enter this on one line):


if (%a == 1 .or. (%b == 2 .and. %c == 3)) echo something


Combining logical expressions


Parentheses can be used only when the portion of the expression inside the parentheses contains at least one of the binary logical operators .and., .or., or .xor.. Parentheses on a simple expression which does not combine two or more tests will be taken as part of the string to be tested, and will probably make the test fail. For example, the first of these tests is FALSE, the second is TRUE:


(a == a)

(a == a .and. b == b)


Parentheses may be nested.




This batch file fragment runs a program called WEEKLY if today is Monday:


if "%_dow" == "mon" weekly


This batch file fragment tests for a string value:


input "Enter your selection : " %%cmd

if "%cmd" == "WP" goto wordproc

if "%cmd" NE "GRAPHICS" goto badentry


This example calls GO.BTM if the first two characters in the file MYFILE are GO:


if "%@left[2,%@line[myfile,0]]" == "GO" call go.btm


The first batch file fragment below tests for the existence of A:\JAN.DOC before copying it to drive C (this avoids an error message if the file does not exist):


if isfile a:\jan.doc copy a:\jan.doc c:\


This example tests the exit code of the previous program and stops all batch file processing if an error occurred:


if errorlevel == 0 goto success

echo "External Error; Batch File Ends!"