Rob van der Woude's Scripting Pages

Batch How To ...

Verify if Variables are Defined

To verify if a variable is defined, we usually check if it has a non-empty value:

IF "%MyVar%"=="" ECHO MyVar is NOT defined

This works, provided the value of MyVar does not contain doublequotes.

In Windows NT 4's CMD.EXE a new IF statement was introduced: IF DEFINED

To quote IF's on-screen help:
The DEFINED conditional [...] takes an environment variable name and returns true if the environment variable is defined.

Note: This does require the Command Extensions to be enabled, so make sure you check this before using IF DEFINED.

The following code will show if a variable MyVar was defined or not:

IF DEFINED MyVar (ECHO MyVar IS defined) ELSE (ECHO MyVar is NOT defined)

The following code, which works in batch files for all MS-DOS, Windows and OS/2 versions, uses an alternative way to show if a variable is defined or not:

IF "%MyVar%"=="" ECHO MyVar is NOT defined
IF NOT "%MyVar%"=="" ECHO MyVar IS defined

Whereas the IF DEFINED method will fail if command extensions are disabled, the second method will fail if MyVar's value contains doublequotes.
Besides, the second method will always fail on the command line in CMD.EXE (though it worked in COMMAND.COM) because undefined variables are treated as literals on the command line.
You may strip MyVar's value of its doublequotes, but then the IF statement might fail if MyVar's value contains characters like >, <, |, & or even parentheses.
So the safest way (for CMD.EXE) seems to be the IF DEFINED method combined with a check if command extensions are enabled:

VERIFY OTHER 2>nul
SETLOCAL ENABLEEXTENSIONS
IF ERRORLEVEL 1 ECHO Unable to enable extensions
IF DEFINED MyVar (ECHO MyVar IS defined) ELSE (ECHO MyVar is NOT defined)
ENDLOCAL

 

Hidden or Dynamic Variables

Now let's investigate variables a little further in Windows NT 4 and later.
Type the following commands on the command line, or copy them to a batch file and run that batch file:

IF "%Date%"=="" (ECHO Date is NOT defined) ELSE (ECHO Date IS defined)
IF DEFINED Date (ECHO Date IS defined) ELSE (ECHO Date is NOT defined)
ECHO Date = %Date%
SET Date

The result will look like this:

C:\>IF DEFINED Date (ECHO Date IS defined )  ELSE (ECHO Date is NOT defined )
Date IS defined

C:\>IF "06-06-2008" == "" (ECHO Date is NOT defined )  ELSE (ECHO Date IS defined )
Date IS defined

C:\>ECHO Date = 06/06/2008
Date = 06-06-2008

C:\>SET Date
Environment variable Date not defined

Note my highlighting: the last command, SET Date, tells us that the variable Date is not defined, but we can clearly see it is.

Let's modify our test batch file:

CLS
IF DEFINED Date (ECHO Date IS defined) ELSE (ECHO Date is NOT defined)
ECHO Date = %Date%
SET Date
PAUSE

SET Date=Some Other Value
IF DEFINED Date (ECHO Date IS defined) ELSE (ECHO Date is NOT defined)
ECHO Date = %Date%
SET Date
PAUSE

SET Date=
IF DEFINED Date (ECHO Date IS defined) ELSE (ECHO Date is NOT defined)
ECHO Date = %Date%
SET Date

Run it again, and the result will look like this:

C:\>IF DEFINED Date (ECHO Date IS defined )  ELSE (ECHO Date is NOT defined )
Date IS defined

C:\>ECHO Date = 06/06/2008
Date = 06/06/2008

C:\>SET Date
Environment variable Date not defined

C:\>PAUSE
Press any key to continue . . .

C:\>SET Date=Some Other Value

C:\>IF DEFINED Date (ECHO Date IS defined )  ELSE (ECHO Date is NOT defined )
Date IS defined

C:\>ECHO Date = Some Other Value
Date = Some Other Value

C:\>SET Date
Date=Some Other Value

C:\>PAUSE
Press any key to continue . . .

C:\>SET Date=

C:\>IF DEFINED Date (ECHO Date IS defined )  ELSE (ECHO Date is NOT defined )
Date IS defined

C:\>ECHO Date = 06/06/2008
Date = 06/06/2008

C:\>SET Date
Environment variable Date not defined

Go ahead, run the batch file several times, and try to figure out what is happening and why.

Hint: In Windows NT 4 and later, Date is one of those variables that are always defined, but don't normally show up in the list when you issue the SET command without any command line arguments. If you set the Date variable yourself, then it does show up in the list.
Other "hidden" variables are __APPDIR__, CD, __CD__, CMDCMDLINE, CMDEXTVERSION, ERRORLEVEL, RANDOM and TIME. For more details, see the SET page.

It looks like these "hidden" variables are defined, but the SET command doesn't see them as defined unless their values are set in the CMD.EXE session (or one of its parent sessions).
By "dropping" their values in the CMD.EXE session (SET Date=), they get back their dynamic (or system) values again.

So now we have a way to check if a "hidden" variable still has its dynamic system value, or a static "custom" value:

SET Date >NUL 2>&1
IF ERRORLEVEL 1 (
	ECHO Date still has its dynamic system value
) ELSE (
	ECHO Date has been set with a static value
)

The following batch file demonstrates the differences between the 4 "defined check methods" for static variable COMSPEC vs all dynamic variables:

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
ECHO Demonstrating check if defined methods for static variable COMSPEC vs dynamic variables
ECHO.
:: COMSPEC is a static variable, the others are dynamic variables
:: SET /P "=text" ^< NUL is used to echo text without linefeed
FOR %%A IN (COMSPEC __APPDIR__ CD __CD__ CMDCMDLINE CMDEXTVERSION DATE ERRORLEVEL RANDOM TIME) DO (

	SET /P "=Using IF DEFINED : " < NUL
	IF DEFINED %%A (
		ECHO Environment variable %%A IS defined
	) ELSE (
		ECHO Environment variable %%A is NOT defined
	)

	SET /P "=Using comparison : " < NUL
	IF "%%~A"=="" (
		ECHO Environment variable %%A is NOT defined
	) ELSE (
		ECHO Environment variable %%A IS defined
	)

	SET /P "=Using SET        : " < NUL
	SET %%A

	SET /P "=Using ECHO       : " < NUL
	ECHO %%A=!%%A!

	ECHO.
)
ENDLOCAL

When run, the output will look like this:

Demonstrating check if defined methods for static variable COMSPEC vs dynamic variables

Using IF DEFINED : Environment variable COMSPEC IS defined
Using comparison : Environment variable COMSPEC IS defined
Using SET        : ComSpec=C:\Windows\system32\cmd.exe
Using ECHO       : COMSPEC=C:\Windows\system32\cmd.exe

Using IF DEFINED : Environment variable __APPDIR__ IS defined
Using comparison : Environment variable __APPDIR__ IS defined
Using SET        : Environment variable __APPDIR__ not defined
Using ECHO       : __APPDIR__=C:\Windows\system32\

Using IF DEFINED : Environment variable CD IS defined
Using comparison : Environment variable CD IS defined
Using SET        : Environment variable CD not defined
Using ECHO       : CD=C:\Scripts

Using IF DEFINED : Environment variable __CD__ IS defined
Using comparison : Environment variable __CD__ IS defined
Using SET        : Environment variable __CD__ not defined
Using ECHO       : __CD__=C:\Scripts\

Using IF DEFINED : Environment variable CMDCMDLINE IS defined
Using comparison : Environment variable CMDCMDLINE IS defined
Using SET        : Environment variable CMDCMDLINE not defined
Using ECHO       : CMDCMDLINE=C:\Windows\system32\cmd.exe  /S /D /c" C:\Scripts\testdefined.bat"

Using IF DEFINED : Environment variable CMDEXTVERSION IS defined
Using comparison : Environment variable CMDEXTVERSION IS defined
Using SET        : Environment variable CMDEXTVERSION not defined
Using ECHO       : CMDEXTVERSION=2

Using IF DEFINED : Environment variable DATE IS defined
Using comparison : Environment variable DATE IS defined
Using SET        : Environment variable DATE not defined
Using ECHO       : DATE=2024-11-22

Using IF DEFINED : Environment variable ERRORLEVEL IS defined
Using comparison : Environment variable ERRORLEVEL IS defined
Using SET        : Environment variable ERRORLEVEL not defined
Using ECHO       : ERRORLEVEL=1

Using IF DEFINED : Environment variable RANDOM IS defined
Using comparison : Environment variable RANDOM IS defined
Using SET        : Environment variable RANDOM not defined
Using ECHO       : RANDOM=14620

Using IF DEFINED : Environment variable TIME IS defined
Using comparison : Environment variable TIME IS defined
Using SET        : Environment variable TIME not defined
Using ECHO       : TIME=01:10:18.35

page last modified: 2024-04-15; loaded in 0.0017 seconds