Windows 如果定义了包含空格的变量名,将使用什么语法进行检查?
Windows用户定义的环境变量名称可以包含除Windows 如果定义了包含空格的变量名,将使用什么语法进行检查?,windows,batch-file,environment-variables,Windows,Batch File,Environment Variables,Windows用户定义的环境变量名称可以包含除=以外的任何字符 特殊字符可以通过转义包含。一种更简单的方法是将整个集合表达式括在引号内。例如: set "A weird & "complex" variable=My value" set A weird ^& "complex" variable=My value 上面的两个表达式给出相同的结果。变量名为一个奇怪且“复杂”的变量,值为我的值 IF-DEFINED构造用于测试是否定义了变量。引号不适用于此测试,名称中的特殊字符(
=
以外的任何字符
特殊字符可以通过转义包含。一种更简单的方法是将整个集合表达式括在引号内。例如:
set "A weird & "complex" variable=My value"
set A weird ^& "complex" variable=My value
上面的两个表达式给出相同的结果。变量名为一个奇怪且“复杂”的变量
,值为我的值
IF-DEFINED构造用于测试是否定义了变量。引号不适用于此测试,名称中的特殊字符(包括引号)必须转义
set "A&B=value"
if defined A^&B echo This works
if defined "A&B" echo This does not work
上述未通过的测试工作正常。引用的测试不起作用
但是如何测试包含空格的变量是否存在
set "A B=value"
if defined A^ B echo this does not work!
看起来上面的方法应该行得通,但是不行
我正在寻找一个答案,它不涉及使用%A B%或!A B 有趣的问题(我喜欢这个语法基础问题)
显然,您知道如何使用延迟扩展来检查它,以及参数的工作情况
@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
在我看来,在escape2示例中,解析器首先以这种方式将行拆分为标记:另一种方法是将其重新分配给另一个变量(一个没有空格的变量)并进行测试。请看这里:
rem Prepare ONLY variable 'a b'
set "a b=123"
echo [a b]=%a b%
rem This will ouput: [a b] is defined
set var=%a b%
if defined var (
echo [a b] is defined
) else (
echo [a b] is not defined
)
rem This will output: [c d] is not defined
set var=%c d%
if defined var (
echo [c d] is defined
) else (
echo [c d] is not defined
)
我也喜欢这样的问题!:)
这是我想出的另一个可能的解决方案。。。使用SET自身测试是否存在,并使用ERRORLEVEL结果:
set "A B=foo"
set A B >nul 2>nul&& echo 1. This works
set "A B ">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
请注意,只有当您的变量是唯一的,即没有变量名是另一个变量的前缀时,这才有效。否则您将面临误报的风险,因为集合的默认行为是显示以您传递的参数开头的所有变量。如果是这种情况,您可以使用findstr筛选结果:
set "A B="
set "A B C=foo"
set "A B ">nul 2>nul&& echo 5. Failed (false positive)
set "A B "|findstr /B /L /C:"A B=" >nul||echo 6. This works (no false positive)
此外,变量名后面的单个尾随空格似乎是必需的。如果没有它,SET常常会错误地解析输入。奇怪的是,如果在“2>nul”和“&&&”之间添加一个额外的空格,以防#3停止工作(除非在“>nul”之前删除空格)。。。奇怪。如果需要,我会将标志定义为TRUE
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=
rem/*示例代码*/
集合变量集=
如果set VAR\u set=TRUE&set VAR=此数据有空格
rem/*使用“如果定义”测试变量集*/
如果定义了VAR_集(
rem/*对变量%VAR%中的其他数据执行某些操作*/
)
rem/*清除标志*/
集合变量集=
FOR/!延迟当我需要睡眠时,解决办法并不明显。当我醒来的时候我就想到了,但是你已经有了一个很好的答案你的分析很有趣。还有一个向陈述中插入评论的机会当然是有效的,但我最初问题的最后一个要求是,我正在寻找一个不使用%a B%或!A B!。(顺便说一句,分配!A B!更安全。分配%A B%可能会失败,具体取决于内容)+1添加FINDSTR的好解决方案。我曾考虑过设置测试并拒绝了它,但没有考虑添加FINDSTR。我仍然更喜欢jeb的解决方案,因为它不需要管道或外部命令,所以速度更快。非常有趣的发现是,任何以“a”匹配开头的变量都需要额外的空间。不需要引用<代码>设置ab
失败<代码>设置ab工作<代码>设置ab失败@杰布-你知道这是怎么回事吗?我在我的评论中添加了一条关于设置空间行为的评论,你还没有回答这个问题-你完全没有抓住要点。
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=