批处理文件中的特殊字符

Mat*_*den 10 windows escaping batch-file

批处理文件中的特殊字符很难,但是我没有找到正确的解决方法来正确地转义这个特定字符串的前两个字符我试图通过该应用程序.

SET pass=^&AntiBatchfileString
A_Program.exe /pass=%pass%
Run Code Online (Sandbox Code Playgroud)

我尝试过的事情:

:: 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%
Run Code Online (Sandbox Code Playgroud)

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

SET "pass=^&AntiBatchfileString"
A_Program.exe "/pass=^^%pass%"
Run Code Online (Sandbox Code Playgroud)

它仍然无法正常工作,我不确定我现在缺少什么.

asc*_*pfl 12

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

set "pass=^&AntiBatchfileString"
Run Code Online (Sandbox Code Playgroud)

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

当扩展(读取)变量"%pass%"(包含"")时,特殊字符仍然按字面处理.

但是,只要你像%pass%(不"")那样展开它们,它们就会恢复它们的特殊含义.所以你有以下选择:

  1. 使用set "pass=^^^&AntiBatchfileString",在阅读时^^逃避文字^^&文字.&%pass%
  2. 启用延迟扩展(请参阅set /?它的工作原理和/ setlocal /?cmd /?如何启用它),其中变量值在特殊字符解析已经完成的时间点展开(读取).

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

然而,%标志不能像^%批处理文件那样被转义,因为百分比扩展在转义之前发生,但是你需要将它们加倍,就像%%每个字符串一样,无论字符串是否介于两者之间"".
请注意,在控制台上,%%不起作用.

最后,文本!被启用后延迟扩展功能消耗,因此您需要特别注意那些情况,通过逃避它们^!,或者通过智能地切换延迟扩展(因此只有在实际需要时才能启用它)否则,在提供文字字符串时禁用它,例如,在set命令行中,例如,在扩展标准变量时,例如%pass%,当读取for变量%%I(例如批处理文件)或%I(控制台)时.当然这也不是最终解决方案,因为您需要setlocalendlocal启用/禁用延迟扩展,这些扩展旨在本地化环境更改,因此自最近setlocal命令以来的任何变量更改都会在endlocal执行后立即丢失(有一些技巧)用于在endlocal屏障上传递变量值).