windows 批处理文件中的特殊字符

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/37333620/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 19:36:16  来源:igfitidea点击:

Special Characters in Batch File

windowsbatch-filecmdescaping

提问by Matthew Rhoden

Special characters in batch files are a pain, but I haven't found the right workaround for properly escaping the first two characters of this particular string I'm trying to pass the application.

批处理文件中的特殊字符很麻烦,但我还没有找到正确的解决方法来正确转义我正在尝试传递应用程序的这个特定字符串的前两个字符。

SET pass=^&AntiBatchfileString
A_Program.exe /pass=%pass%

Things I have tried:

我尝试过的事情:

:: Escaping the escape twice, first for ^, second for &.
SET pass=^^^^&AntiBatchfileString
echo %pass%

:: Combining escapes.
SET first=^^
SET second=^^&AntiBatchfileString
SET pass=%first%%second%
echo %pass%

:: Preventing expansion
SET first=^^
SET second=^^&AntiBatchfileString
SET pass=!first!%second%
echo %pass%

:: I got this to print correctly
SET "pass=^&AntiBatchfileString"
echo ^^%pass%

Still when passing the last one it doesn't accept the login, I don't know what the final output is. That got me thinking maybe it was trying to do another expansion when passing the parameter to the application, so I quoted that as well.

仍然通过最后一个时它不接受登录,我不知道最终输出是什么。这让我想到在将参数传递给应用程序时它可能正在尝试进行另一个扩展,所以我也引用了它。

SET "pass=^&AntiBatchfileString"
A_Program.exe "/pass=^^%pass%"

It's still not working, I'm not sure what I'm missing at this point.

它仍然无法正常工作,我不确定此时我缺少什么。

回答by aschipfl

Supposing you want the string ^&AntiBatchfileStringliterally, this is the best setsyntax, as most special characters (^&()<>|and also the standard delimiters ,;=SPACETAB) lose their particular meaning as soon as ther are placed in between "", and the ""themselves do not become part of the variable value:

假设您想要^&AntiBatchfileString字面上的字符串,这是最好的set语法,因为大多数特殊字符(^&()<>|以及标准分隔符,;=SPACETAB)一旦放在 之间就失去了它们的特定含义"",并且""它们本身不会成为变量值的一部分:

set "pass=^&AntiBatchfileString"

This works only as long as the command extensions are on, which is the Windows default anyway (type cmd /?and see the /Eoption).

这仅在命令扩展打开时才有效,无论如何这是 Windows 默认的(键入cmd /?并查看/E选项)。

When expanding (reading) a variable like "%pass%"(with enclosing ""), special characters are still treated literally.

当扩展(读取)一个像"%pass%"(用封闭"")这样的变量时,特殊字符仍然按字面处理。

However, as soon as you expand it like %pass%(no ""), they get back their special meaning. So you have the following options:

然而,一旦你像%pass%(no "")一样扩展它,它们就会恢复它们的特殊含义。因此,您有以下选择:

  1. Use set "pass=^^^&AntiBatchfileString", where ^^escapes the literal ^and ^&the literal &when reading like %pass%.
  2. Enable delayed expansion (see set /?about how it works and setlocal /?or cmd /?about how to enable it), where the variable value is expanded (read) at a point of time where parsing of special characters has already been completed.
  1. 使用set "pass=^^^&AntiBatchfileString", where在阅读时^^转义文字^^&文字.&%pass%
  2. 启用延迟扩展(查看set /?它是如何工作的和/setlocal /?cmd /?如何启用它),在特殊字符解析已经完成的时间点扩展(读取)变量值。

I prefer the latter approach, because no special escaping is necessary, and it can also deal with "appearing in the string value (even if unsymmetrically present).
By the way, "can also be escaped by ^", as long as this does not appear within unescaped "".

我更喜欢后一种方法,因为不需要特殊的转义,它也可以处理"出现在字符串值中(即使不对称存在)。
顺便说一下,"也可以由 转义^",只要这不在 unescaped 中出现即可""

Nevertheless, %signs cannot be escaped like ^%in a batch file, because percent expansion happens before escaping, but you need to double them like %%to get one literal one each, independent whether or not the string is in between "".
Note that on the console, %%does not work.

然而,%符号不能像^%在批处理文件中那样被转义,因为百分比扩展发生在转义之前,但是你需要将它们加倍,就像%%得到一个文字一个一样,独立于字符串是否在 之间""
请注意,在控制台上,%%不起作用。

Finally, literal !are consumed by the delayed expansion feature when enabled, therefore you need to pay particular attention to those in case, by escaping them like ^!, or also by intelligently toggling delayed expansion (hence to enable it only when it is actually needed and to disable it otherwise, when a literal string is provided, like in a setcommand line, for instance, when expanding a standard variable like %pass%and when reading a forvariable like %%I(batch file) or %I(console), for example). Of course this is also not the ultimate solution, because you need setlocaland endlocalto enable/disable delayed expansion, which are intended to localise environment changes, so any variable changes since the most recent setlocalcommand are lost as soon as endlocalis executed (there are some tricks for passing a variable value over the endlocalbarrier though).

最后,文字!在启用时被延迟扩展功能消耗,因此您需要特别注意那些以防万一,通过像 转义它们^!,或者智能地切换延迟扩展(因此仅在实际需要时才启用它,并且否则禁用它,当提供文字字符串时,例如在set命令行中,例如,在扩展标准变量时%pass%以及读取for变量时%%I(例如(批处理文件)或%I(控制台))。当然,这也不是最终的解决办法,因为你需要setlocalendlocal启用/禁用延迟扩展,其目的本地化环境的变化,所以从最近的任何变量的变化setlocal命令一endlocal执行就会丢失(尽管有一些技巧可以将变量值传递到endlocal屏障上)。