What syntax will check if a variable name containing spaces is defined?

User-defined Windows environment variable names can contain any character except = .

Special characters can be included by escaping them. The simplest method is to simply enclose the complete SET expression in quotation marks. For instance:

 set "A weird & "complex" variable=My value" set A weird ^& "complex" variable=My value 

Both expressions above give the same result. The name of the variable is A weird & "complex" variable , and the value is My value

The IF DEFINED clause is used to check if a variable is defined. Quotations do not work for this test, special characters in the name (including quotation marks) must be escaped.

 set "A&B=value" if defined A^&B echo This works if defined "A&B" echo This does not work 

The above runaway test works just fine. The cited test does not work.

But how can I check if a variable containing spaces exists?

 set "AB=value" if defined A^ B echo this does not work! 

It seems that the above should work, but it is not!

I am looking for an answer that DOES NOT include variable expansion using% AB% or! AB!

+6
source share
4 answers

Interesting question (I like these basic syntax questions).

Obviously, you know how to test it with extension delay, as well as FOR parameters.

 @echo off setlocal set "AAA BBB=value" set ""AAA BBB"=" set "AAA=" for %%a in ("AAA BBB") do if defined %%~a echo FOR: This works setlocal EnableDelayedExpansion set "varname=AAA BBB" if defined !varname! echo Delayed: This works if defined %varname% ( echo percent: Never comes here ) ELSE ( echo percent: Never comes here ? ) if defined AAA^ BBB ( echo escape1: Never comes here ) ELSE ( echo escape1: fails ) set AAA=Hello if defined AAA^ BBB ( echo escape2: It only test for AAA the BBB will be "removed" ) ELSE ( echo escape2: fails ) set "space= " if defined AAA!space!BBB echo inject space: This works if defined "AAA BBB" (echo Quote1: Never comes here ) ELSE ( echo Quote1: Fails ) set ""AAA BBB"=value" if defined "AAA BBB" echo Quote2: This works, it checks for "AAA BBB" with quotes 

In my example, in the escape2 example, the parser first split the string into tokens as follows:
<if> <defined> <AAA BBB> <echo .... But at run time if, if it is defined, it re-looks at the <AAA BBB> token, so it only gets AAA .
You cannot enter a second escape, for example AAA^^^ BBB , since it only searches for a variable named AAA^

I don't see a solution without the / FOR delay, since escaping space always fails.

EDIT: it can also be solved with SET <varname>
The ijprest solution uses the SET command to test a variable without the need to escape the var name.
But it also shows interessting behavior with spaces inside and at the end of varname.

These rules seem to follow:
SET varname searches for all variables starting with varname, but first removes all characters after the last space character varname and removes all leading spaces. Thus, you cannot search for variables beginning with a space (but it is also difficult to create such a varname).

The same behavior is also active if the variable name is enclosed in quotation marks, but then another rule exists.
First delete all characters after the last quote if there are at least two quotation marks. Use the text inside quotation marks and use the "space" -rule.

Example.

 set " abc def ghi" junk junk *** 1. removes the junk set " abc def ghi" *** 2. removes the quotes set abc def ghi *** 3. removes all after the last space, and the trailing spaces set abc def *** Search all variables beginning with abc def 
+5
source

I also like this question! :)

Here is another possible solution that I came across ... using SET to check for the existence and use of the ERRORLEVEL result:

 set "AB=foo" set AB >nul 2>nul&& echo 1. This works set "AB ">nul 2>nul&& echo 2. This works set "A weird & "complex" variable=foo" set A weird ^& "complex" variable >nul 2>nul&& echo 3. This works set "A weird & "complex" variable ">nul 2>nul&& echo 4. This works 

Please note that this only works if your variables are unique in the sense that the variable name is not a prefix of another. Otherwise, you risk false positives, since the default behavior of SET should show all variables starting with the passed parameter. If this may be the case, you can filter the results with findstr:

 set "AB=" set "ABC=foo" set "AB ">nul 2>nul&& echo 5. Failed (false positive) set "AB "|findstr /B /L /C:"AB=" >nul||echo 6. This works (no false positive) 

In addition, a single trailing space after the variable name is required. Without it, SET often parses input incorrectly. Unusually, if you add extra space between "2> nul" and "& &" in case # 3, it stops working (unless you remove the space before "> nul") ... strange.

+3
source

Another way is to reassign it to another variable (without spaces) and check it. See here:

 rem Prepare ONLY variable 'ab' set "ab=123" echo [ab]=%ab% rem This will ouput: [ab] is defined set var=%ab% if defined var ( echo [ab] is defined ) else ( echo [ab] is not defined ) rem This will output: [cd] is not defined set var=%cd% if defined var ( echo [cd] is defined ) else ( echo [cd] is not defined ) 
0
source

I do this by defining the flag as true if necessary ...

 rem /* sample code */ set VAR_SET= if <some condition> set VAR_SET=TRUE&set VAR=this data has spaces rem /* test for VAR_SET using 'if defined' */ if defined VAR_SET ( rem /* do something with the other data in the variable %VAR% */ ) rem /* clear the flag */ set VAR_SET= 
-2
source

Source: https://habr.com/ru/post/902285/


All Articles