39

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?

Community
  • 1
  • 1
Johann
  • 4,107
  • 3
  • 40
  • 39
  • 1
    At the command line you can just use the `SET` command to check if a variable is defined. – RBarryYoung May 03 '13 at 21:35
  • 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 May 03 '13 at 21:49
  • Why would you need to use the IF at the command line? Just look at it and take the appropiate action. – RBarryYoung May 03 '13 at 22:00
  • 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." (https://code.google.com/p/gyp/wiki/InputFormatReference#Command_Expansions_(<!,_<!@)). 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 May 03 '13 at 22:04
  • 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 Apr 21 '14 at 15:54
  • [What is the proper way to test if variable is empty in a batch file?](http://stackoverflow.com/q/2541767/995714) – phuclv May 20 '17 at 14:15

5 Answers5

35

Errr... just:

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

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

Simon Catlin
  • 2,141
  • 1
  • 13
  • 15
10

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.

jeb
  • 78,592
  • 17
  • 171
  • 225
  • excelent solution... the best for the case... great idea to force a literal... THX! – ZEE Feb 07 '17 at 22:20
8

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.

RBarryYoung
  • 55,398
  • 14
  • 96
  • 137
  • Won't work as written in this context, because the OP needs a single-line command. I imagine you could join them up easily enough. – Harry Johnston May 05 '13 at 22:25
  • @HarryJohnston I see no mention of that requirement by the OP. This meets all of the OP's stated requirements. – RBarryYoung May 06 '13 at 00:02
  • The gyp reference page the OP links to does not indicate any method to pass a multiple-line command to the shell. – Harry Johnston May 06 '13 at 01:40
  • When I wrote this question two years ago, I was careful to avoid references to `gyp`, since I didn't want to conflate issues. This answer satisfies the original question, though I never took the time to see if I could make it work with gyp. (IIRC, I took the easy way out and ended up assuming that command extensions would be enabled.) – Johann May 27 '15 at 20:00
  • For future reference, I believe this will also give you the wrong answer if there is a defined variable whose name begins with the name you're interested in, e.g., if you're checking whether `FOO` is defined, and there is a variable `FOOBAR` defined. – Harry Johnston May 22 '18 at 19:52
5

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
James L.
  • 9,384
  • 5
  • 38
  • 77
  • I got: ```"PATH" exists``` ```"PATHX" exists```. Any idea why that might be? – Johann May 03 '13 at 21:55
  • What OS are you using? You might add `set x=` between the two sections just to be sure that `x` is undefined before the 2nd instance... Unless you have a `pathx` environment variable! Have you typed `set pathx` to see? – James L. May 03 '13 at 22:53
  • Adding `set x=` between the sections didn't change it. I still get `"PATH" exists` `"PATHX" exists` on both Windows XP SP3, and two different Windows 7 SP1 machines. – Johann May 04 '13 at 00:02
  • Works fine for me. Try leaving echo on to see what's happening. – Harry Johnston May 04 '13 at 05:51
  • 1
    But it will not work on the command line, only in a batch file – jeb May 04 '13 at 08:51
  • @jeb: looks like James and I both misinterpreted the question! – Harry Johnston May 05 '13 at 22:24
1
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.