"..."和"..."之间有什么区别?和x"..." Windows批处理文件中是否处于IF条件? [英] What is the difference between "..." and x"..." in an IF condition in a Windows batch file?
问题描述
我最近找到了帖子查找子字符串是否在字符串中(而不是在文件中),其中指出了考虑
I recently found the post Find if substring is in string (not in a file) where it is stated that considering
@setlocal enableextensions enabledelayedexpansion
@echo off
set str1=%1
if not x%str1:bcd=%==x%str1% echo It contains bcd
endlocal
然后
等号两边之前的
x
是为了确保字符串bcd
正常工作.它还可以防止某些不合适的"起始字符.
the
x
before the two sides of the equality is to ensure that the stringbcd
works okay. It also protects against certain "improper" starting characters.
但是,我还没有找到关于此x
实际效果的任何解释.那么x"%string%"
和"%string%"
有什么区别?
However, I haven't found any explanation about the actual effect of this x
. So what is the difference between x"%string%"
and "%string%"
?
推荐答案
这只是一个非常糟糕的编码字符串比较.两侧的x
使得即使在执行命令 IF 之前,Windows命令处理器在将整个命令行解析为空字符串后,即使Windows处理器将%str1:bcd=%
或%str1%
替换为空,也可以比较两个字符串. >.
That is simply a very bad coded string comparison. The x
on both sides makes it possible to compare the two strings even if %str1:bcd=%
or %str1%
is substituted by Windows command processor on parsing entire command line by an empty string before execution of command IF.
但是,由于在环境变量str1
的值包含空格字符或"&<>|
的情况下出现语法错误,因此批处理文件的执行仍然被cmd.exe
立即退出.
But the batch file execution is nevertheless exited immediately by cmd.exe
because of a syntax error in case of value of environment variable str1
contains a space character or "&<>|
.
将参数字符串括在双引号中会导致获得除百分号以外的所有字符,并且启用了延迟的环境变量扩展,还会将感叹号解释为文字字符,包括在双引号字符串之外的空格(其解释为参数字符串分隔符).
Enclosing an argument string in double quotes results in getting all characters except percent sign and with enabled delayed environment variable expansion also the exclamation mark interpreted as literal character including space which is outside a double quoted string interpreted as argument string separator.
更好的是:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
if "%~1" == "" goto EndBatch
set "str1=%~1"
if not "%str1:bcd=%" == "%str1%" echo It contains bcd
:EndBatch
endlocal
首先比较批处理文件的第一个参数,而不用空字符串将双引号引起来.因此,如果启动批处理文件时不带任何参数,或者仅使用""
作为第一个参数字符串,则Windows命令处理器将执行命令 GOTO ,从而恢复使用命令 SETLOCAL <压入堆栈的先前环境./strong>,然后退出批处理文件.
The first argument of the batch file is compared first without surrounding double quotes with an empty string. So if the batch file is started without any argument or with just ""
as first argument string, Windows command processor executes the command GOTO resulting in restoring previous environment pushed on stack with command SETLOCAL and exits the batch file.
否则,批处理文件实际上使用参数字符串来调用.将此参数字符串分配给环境变量str1
,并删除周围的双引号(如果有的话).因此,在使用参数test
调用批处理文件时,将值test
分配给环境变量str1
,并且在使用"another test"
进行调用时,将不带双引号的值another test
分配给str1
.甚至在使用错误的编码参数字符串"bcd test
(缺少第二个"
)调用批处理文件时,也只会将bcd test
分配给环境变量str1
.
Otherwise the batch file is called really with an argument string. This argument string is assigned to environment variable str1
with removing surrounding double quotes if there are one. So on calling batch file with argument test
the value test
is assigned to environment variable str1
and on calling it with "another test"
the value another test
without the double quotes is assigned to str1
. And even on calling the batch file with wrong coded argument string "bcd test
(missing second "
) just bcd test
is assigned to the environment variable str1
.
IF 条件将环境变量str1
的值与所有出现的bcd
删除后的值与未修改的变量值进行比较.即使在包含空格或与号或重定向运算符<>|
的情况下,两个字符串周围的双引号也可以比较两个字符串.命令 IF 包含在比较两个字符串时的双引号.
The IF condition compares the value of environment variable str1
with all occurrences of bcd
removed with the unmodified variable value. The double quotes around the two strings make it possible to compare the two strings even on containing space or ampersand or the redirection operators <>|
. The command IF includes the double quotes on comparing the two strings.
那么这段代码现在安全吗?
So is this code now safe?
否,不是有人用test_bcd"
作为缺少第一双引号的参数字符串将批处理文件称为无效的情况.在这种情况下,cmd.exe
执行的第一个 IF 命令行是:
No, it is not in case of somebody calls the batch file invalid with test_bcd"
as argument string on which first double quote is missing. In this case the first IF command line executed by cmd.exe
is:
if "test_bcd"" == "" goto EndBatch
错误的指定参数字符串的尾随的"
不会被cmd.exe
删除,并在执行此命令行时导致语法错误,因为可以从命令提示符窗口中运行批处理文件时看到,首先显示行修改为@echo on
.
The trailing "
of the wrong specified argument string is not removed by cmd.exe
and cause a syntax error on this command line on execution as it can be seen on running the batch file from within a command prompt window with first line modified to @echo on
.
不使用延迟的环境变量扩展的一种解决方案是:
One solution without using delayed environment variable expansion is:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "str1=%~1"
if not defined str1 goto EndBatch
set "str1=%str1:"=%"
if not defined str1 goto EndBatch
if not "%str1:bcd=%" == "%str1%" echo It contains bcd
:EndBatch
endlocal
此代码可确保在执行 IF 命令比较字符串之前,str1
不包含任何双引号.
This code makes sure that str1
does not contain any double quote before executing the IF command comparing the strings.
另一种解决方案是使用延迟的环境变量扩展:
Another solution is using delayed environment variable expansion:
@echo off
setlocal EnableExtensions EnableDelayedExpansion
set "str1=%~1"
if not "!str1:bcd=!" == "!str1!" echo It contains bcd
endlocal
作为上面的代码,在不使用延迟的环境变量扩展的情况下,它看起来更好.但是,如果参数字符串是例如"!Hello!"
,则它不能按预期方式工作,因为在这种情况下,if not
条件也为true,因此输出为消息It contains bcd
,尽管字符串!Hello!
不包含
That looks better as the above code without usage of delayed environment variable expansion. But it does not work as expected if the the argument string is for example "!Hello!"
because in this case the if not
condition is also true and output is therefore the message It contains bcd
although the string !Hello!
does not contain bcd
.
解决方案是:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "str1=%~1"
setlocal EnableDelayedExpansion
if not "!str1:bcd=!" == "!str1!" echo It contains bcd
endlocal
endlocal
在将参数字符串分配给环境变量str1
时未启用延迟扩展,这导致将字符串"!Hello!"
中的感叹号解释为文字字符.然后启用延迟扩展以使用延迟环境变量扩展进行字符串比较,从而避免在执行 IF 命令之前使用cmd.exe
修改命令行本身.
Delayed expansion is not enabled on assigning the argument string to environment variable str1
which results in getting the exclamation marks in string "!Hello!"
interpreted as literal characters. Then delayed expansion is enabled for making the string comparison with using delayed environment variable expansion which avoids that the command line itself is modified by cmd.exe
before execution of IF command.
要了解所使用的命令及其工作方式,请打开命令提示符窗口,在其中执行以下命令,并非常仔细地阅读每个命令显示的所有帮助页面.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
-
call /?
...解释%~1
,效果不如此处完成. -
echo /?
-
endlocal /?
-
goto /?
-
if /?
-
set /?
-
setlocal /?
call /?
... explains%~1
, not so good as done here.echo /?
endlocal /?
goto /?
if /?
set /?
setlocal /?
另请参阅:
- Windows命令解释器(CMD.EXE)如何解析脚本? ...每个批处理文件的答案很长作家应该从上到下仔细阅读.
- forfiles-假与假(不适用于小写字母吗?) ...这个答案是关于命令 IF 的参数处理.
- 等效于Windows批处理文件中NEQ,LSS,GTR等的符号 ...此答案详细说明了如何通过命令 IF 完成字符串比较.
- 为什么在命令行上使用'set var = text'后,为什么没有字符串显示'echo%var%'? ...此答案说明了为什么应普遍使用
set "variable=value"
而不是其他变体. - 使用Windows批处理文件的单行多命令 ...说明了如何在用双引号引起来的字符串由
cmd.exe
解释. - 有关使用命令重定向运算符解释了
cmd.exe
如何解释双引号参数字符串之外的<>|&
.
- How does the Windows Command Interpreter (CMD.EXE) parse scripts? ... a long answer every batch file writer should read carefully from top to bottom.
- forfiles - FALSE vs. false (doesn't work with lower case?) ... this answer is about argument processing of command IF.
- Symbol equivalent to NEQ, LSS, GTR, etc. in Windows batch files ... this answer explains in detail how string comparisons are done by command IF.
- Why is no string output with 'echo %var%' after using 'set var = text' on command line? ... this answer explains why
set "variable=value"
should be used in general and not other variants. - Single line with multiple commands using Windows batch file ... explains how
&
and||
outside a double quoted argument string are interpreted bycmd.exe
. - Microsoft article about Using command redirection operators explains how
<>|&
outside a double quoted argument string are interpreted bycmd.exe
.
这篇关于"..."和"..."之间有什么区别?和x"..." Windows批处理文件中是否处于IF条件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!