什么语法将检查是否定义了包含空格的变量名?
Windows 用户定义的环境变量名称可以包含除 =
之外的任何字符。
可以通过转义特殊字符来包含它们。一种更简单的方法是简单地将整个 SET 表达式括在引号内。例如:
set "A weird & "complex" variable=My value"
set A weird ^& "complex" variable=My value
上面的两个表达式给出相同的结果。变量名称是一个奇怪的& “complex”变量
,值为我的值
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!
看起来上面的方法应该有效,但事实并非如此!
我正在寻找一个不涉及使用 %AB% 或 !AB! 扩展变量的答案
Windows user defined environment variable names can contain any character except =
.
Special characters can be included by escaping them. A simpler method is to simply enclose the entire SET expression within quotes. For example:
set "A weird & "complex" variable=My value"
set A weird ^& "complex" variable=My value
Both expressions above give the same result. The variable name is A weird & "complex" variable
and the value is My value
The IF DEFINED construct is used to test if a variable is defined. Quotes don't work for this test, special characters in the name (including quotes) 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 escaped test works just fine. The quoted test does not work
But how can I test if a variable containing spaces exists?
set "A B=value"
if defined A^ B echo this does not work!
It seems like the above should work, but it doesn't!
I'm looking for an answer that does NOT involve expanding the variable using %A B% or !A B!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
有趣的问题(我喜欢这个语法基础问题)。
显然,您知道如何通过延迟扩展来检查它,并且 FOR 参数也有效。
在我看来,在 escape2 示例中,解析器首先以这种方式将行拆分为标记:<回声....
<代码><如果> <定义>
但在 if Defined 执行时,它会重新扫描
令牌,因此它只获取AAA
。您不能注入像
AAA^^^ BBB
这样的第二个转义符,因为它只搜索名为AAA^
的变量,如果不延迟/FOR,我看不到解决方案,因为逃离空间总是失败。
编辑:也可以用
SET
解决
ijprest的解决方案是使用SET命令来测试变量,而不需要对varname进行转义。
但它也显示了变量名称内部和末尾的空格的有趣行为。
它似乎遵循以下规则:
SET varname
搜索以 varname 开头的所有变量,但首先删除 varname 最后一个空格字符之后的所有字符,并删除所有前导空格。所以你不能搜索以空格开头的变量(但创建这样的变量名也有点棘手)。
如果变量名括在引号中,则同样的行为也处于活动状态,但随后又存在一条规则。
如果至少有两个引号,请首先删除最后一个引号之后的所有字符。
使用引号内的文本,并使用“空格”规则。
样本。
Interessting question (I love this syntax base questions).
Obviously you know how to check it with delayed expansion and also FOR-parameters works.
In my opionion, in the escape2 example the parser first split the line into tokens this way:
<if> <defined> <AAA BBB> <echo ....
But at the execution time of the if defined it rescan the
<AAA BBB>
token so it only gets theAAA
.You can't inject a second escape like
AAA^^^ BBB
as this only searches for the variable namedAAA^
I can't see a solution without delaying/FOR, as the escaping of the space always fails.
EDIT: It can also be solved with
SET <varname>
The solution of ijprest uses the SET command to test the variable without the need of escaping the varname.
But it also shows interessting behaviour with spaces inside and at the end of a varname.
It seems to follow these rules:
SET varname
searches for all variables beginning with varname, but first it removes all characters after the last space character of varname, and it removes all leading spaces.So you can't search for variables with beginning with space (but it is also a bit tricky to create such a varname).
The same behaviour is also active if the variablename is enclosed into quotes, but then exists one more rule.
First remove all characters after the last quote, if there are at least two quotes.
Use the text inside of the quotes, and use the "space"-rule.
Sample.
我也喜欢问这种问题! :)
这是我想出的另一个可能的解决方案...使用 SET 本身来测试是否存在,并使用 ERRORLEVEL 结果:
请注意,只有当您的变量是唯一的(即没有变量)时,这才有效name 是另一个的前缀。否则,您将面临误报的风险,因为 SET 的默认行为是显示以您传递的参数开头的所有变量。如果是这种情况,您可以使用 findstr 过滤结果:
此外,变量名称后面的单个尾随空格似乎是必需的。如果没有它,SET 经常会错误地解析输入。奇怪的是,如果您在“2>nul”和“&&”之间添加额外的空格如果#3它停止工作(除非你删除“>nul”之前的空格)......很奇怪。
I also love this sort of question! :)
Here's another possible solution I came up with... using SET itself to test the existence, and using the ERRORLEVEL result:
Note that this only works if your variables are unique in the sense that no variable name is the prefix of another one. Otherwise you risk false positives, as SET's default behavior is to show all variables that start with the parameter you pass. If this could be the case, you could filter the results with findstr:
Also, the single trailing space after the variable name seems to be required. Without it, SET often mis-parses the input. Bizarrely, if you add an extra space between the "2>nul" and "&&" in case #3 it stops working (unless you remove the space before ">nul")... weird.
另一种方法是将其重新分配给另一个变量(没有空格的变量)并测试该。参见这里:
The other way is to reassign it to another variable (one without spaces) and test that. See here:
如果需要的话,我通过将标志定义为 TRUE 来做到这一点......
I do it by defining a flag as TRUE if needed...