"..."和"..."之间有什么区别?和x"..." Windows批处理文件中是否处于IF条件? [英] What is the difference between "..." and x"..." in an IF condition in a Windows batch file?

查看:77
本文介绍了"..."和"..."之间有什么区别?和x"..." Windows批处理文件中是否处于IF条件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近找到了帖子查找子字符串是否在字符串中(而不是在文件中),其中指出了考虑

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 string bcd 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 /?

另请参阅:

  • 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 by cmd.exe.
  • Microsoft article about Using command redirection operators explains how <>|& outside a double quoted argument string are interpreted by cmd.exe.

这篇关于"..."和"..."之间有什么区别?和x"..." Windows批处理文件中是否处于IF条件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆