39
votes

I need to use a cmd.exe command line (cmd.exe is being called from the gyp build tool) to determine whether an environment variable is defined or not. How can I do this? I am okay assuming that the variable value does not contain single or double quotes, but cannot assume that command extensions are enabled.

I've tried the following, which works great in a .bat file, but fails when typed directly on the command line:

IF "%UNDEFINED%" == "" (echo yes)

When that exact line is in a .bat file and executed, I see yes as the output. When I type it on the command line, the output is empty. I am testing this on Windows XP SP3, though my coworker sees the same results on Windows 7. This is the method suggested by http://support.microsoft.com/kb/121170 and http://www.robvanderwoude.com/battech_defined.php. I do not want to use IF DEFINED UNDEFINED (echo yes) because that won't work if command extensions are disabled.

The top-voted answer in the following post has led me to believe that this issue is related to how percent-expansion is handled differently in the "CmdLineParser" vs. the "BatchLineParser," but still has not led me to a solution: How does the Windows Command Interpreter (CMD.EXE) parse scripts?

5
At the command line you can just use the SET command to check if a variable is defined.RBarryYoung
How would I use that in a conditional check? I tried: IF (SET UNDEFINED) (echo yes) and got UNDEFINED) was unexpected at this time.Johann
Why would you need to use the IF at the command line? Just look at it and take the appropiate action.RBarryYoung
The reason is that this is being used within a gyp build file, and the gyp reference says: "In a command expansion, the entire string contained within the parentheses is passed to the system’s shell." (code.google.com/p/gyp/wiki/…). However, when I use the IF "%VARIABLE%" == "" syntax, it never evaluates to true, even when VARIABLE is not defined. I'm assuming it's because it's running through the same command line parser. IF DEFINED does work as expected, but I cannot guarantee that command extensions will be enabled.Johann
I think @RBarryYoung provided the answer. Use set with no args to print the environment, and use find to find the variable. I was going to post an answer with the same. But because of Barry's answer, it simply would have been a "me too" answer.jww

5 Answers

36
votes

Errr... just:

if defined your-var-name ( 
    echo yarp
) else (
    echo narp
)

I should add, I do not believe this needs command extensions...

9
votes

If the extensions are really disabled (I can't believe this),
then you can try different ways.

IF %UNDEFINED% == %^UNDEFINED% (echo yes)

This works as if undefined doesn't exists then it isn't replaced, also ^undefined but the caret will be removed in the next parser phase, so %undefined% is compared against %undefined%. The disadvantage are the missing quotes, as they also make the expression stable against special characters.

A better way is to use IF defined, but when extensions are disabled you need to enable them first.

cmd /E:on /c "if not defined undefined echo It's undefined"

The best way is to simply use a batch file, that should also work with gyp build system.

8
votes

OK, this took a bit, but I think I've figured it out. Try this:

SET UNDEFINED 2>Nul | Findstr/I "."
IF ERRORLEVEL 1  ECHO Not Defined.

This works for all cases AFAIK, and does not rely on any command extension features.

5
votes

I tried this and it worked:

@echo off

setlocal disableextensions

set x=%path%
if "%x%"=="" (echo "PATH" does not exist) else (echo "PATH" exists)

set x=%pathx%
if "%x%"=="" (echo "PATHX" does not exist) else (echo "PATHX" exists)

endlocal

It returned:

"PATH" exists
"PATHX" does not exist
1
votes
IF NOT %CODE%==? do stuff.

This works on a W98 command line and in a batch file, so it ought to work anywhere from early MS-DOS onwards with no extensions needed. It assumes that CODE is usefully set or not set at all.

It results in a syntax error if CODE does not exist, or does nothing if CODE is a question mark (chosen because it could never exist in a path). Either way, nothing is done. The NOT makes sure action is only taken if CODE appears to be set to something useful.

I use it in compiler batch files to determine whether to use relative paths or use a fixed base directory if one is set in the CODE variable. It allows me to make a coding tree portable without having to modify all the batch files for each program if I move everything.