批处理文件中的特殊字符

11

批处理文件中的特殊字符很让人头痛,但是我还没有找到合适的解决方法来正确转义我正试图传递给应用程序的字符串的前两个字符。

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

我尝试过的事情:

:: 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%

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

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

它仍然不起作用,我不确定此时我缺少了什么。


可能是批处理字符转义的重复问题。 - phuclv
2个回答

20

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

set "pass=^&AntiBatchfileString"

只有在命令扩展开启时,它才能正常工作,这也是Windows的默认设置(键入 cmd /? 并查看 /E 选项)。

当扩展(读取)类似于 "%pass%"(用引号括起来)的变量时,特殊字符仍然被按字面意义处理。

但是,一旦像 %pass%(没有 "")这样扩展它,它们就会恢复其特殊含义。所以你有以下选择:

  1. 使用 set "pass=^^^&AntiBatchfileString",其中 ^^ 转义字面上的 ^^& 转义字面上的 &,以便读取类似于 %pass% 的变量。
  2. 启用延迟扩展(参见 set /? 了解其工作方式,以及有关如何启用它的 setlocal /?cmd /?),其中变量值在已完成特殊字符解析的时间点进行扩展(读取)。

我更喜欢后一种方法,因为不需要特殊转义,而且还可以处理字符串值中出现的 "(即使不对称地存在)。
顺便说一下,可以通过 ^" 转义 ",只要它没有出现在未转义的 "" 中。

然而,在批处理文件中无法像使用 ^% 转义百分号,因为百分号扩展会发生在转义之前,但是您需要将它们加倍,例如使用 %% 来获得一个独立的字面百分号,无论字符串是否在 "" 中。
请注意,控制台上不支持 %%

最后,当启用延迟扩展功能时,字面上的 ! 会被消耗掉,因此您需要特别注意这些内容,并像使用 ^! 转义它们,或者通过智能地切换延迟扩展来解决问题(因此仅在实际需要时启用它,在提供文字字符串时禁用它,例如在 set 命令行中扩展标准变量,例如 %pass%,以及在读取像 %%I(批处理文件)或 %I(控制台)这样的 for 变量时)当然,这也不是最终解决方案,因为您需要使用 setlocalendlocal 来启用/禁用延迟扩展,这些命令旨在本地化环境更改,因此自最近的 setlocal 命令以来的任何变量更改都会在执行 endlocal 时丢失(但有一些技巧可以通过 endlocal 的障碍来传递变量值)。


啊,我现在明白了。在折腾了这么久之后,我没有意识到在尝试其他东西时留下了"/pass=%pass%"这一部分。现在它可以工作了,感谢你的提示,@aschipfl! - Matthew Rhoden

0
如果你想在批处理文件中使用未转义的字符串 %:
就像 %20 一样,你可以使用 %%%20
git clone "https:// abc.com /D%%%220an"

一个批处理文件里不是两个百分号就足够了吗?为什么这里有三个? - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接