use*_*213 5 escaping batch-file
我正在尝试回显存储在变量中的字符串,但它似乎需要大量的转义.我正在尝试使用以下代码:
setlocal EnableDelayedExpansion
@echo off
set "grass=@##&!$^&%**(&)"
echo !grass!
Run Code Online (Sandbox Code Playgroud)
我想grass逐字回显变量,所以我@##&!$^&%**(&)在输出中看到了一个.应该做什么?谢谢!
dbe*_*ham 13
echo !grass!将始终逐字回显当前值,而无需任何转义.你的问题是,价值不是你想象的那样!当您尝试设置值时,会发生此问题.
设置值的正确转义序列是
set "grass=@##&^!$^^&%%**(&)"
Run Code Online (Sandbox Code Playgroud)
现在来解释一下.您需要的信息隐藏在Windows命令解释器(CMD.EXE)如何解析脚本?.但它有点难以理解.
你有两个问题:
1)%必须进行转义,%%因为每次解析该行.引号的存在与否都没有区别.延迟扩张状态也没有区别.
set pct=%
:: pct is undefined
set pct=%%
:: pct=%
call set pct=%%
:: pct is undefined because the line is parsed twice due to CALL
call set pct=%%%%
:: pct=%
Run Code Online (Sandbox Code Playgroud)
2)当解析器的延迟扩展阶段解析时,!必须转义文字^!.如果一行包含!延迟扩展期间的任何位置,则^必须将文字转义为^^.但是,^必须引用或转义^^解析器的特殊字符阶段.由于CALL会使任何^字符加倍,这可能会进一步复杂化.(抱歉,描述问题非常困难,解析器很复杂!)
setlocal disableDelayedExpansion
set test=^^
:: test=^
set "test=^"
:: test=^
call set test=^^
:: test=^
:: 1st pass - ^^ becomes ^
:: CALL doubles ^, so we are back to ^^
:: 2nd pass - ^^ becomes ^
call set "test=^"
:: test=^^ because of CALL doubling. There is nothing that can prevent this.
set "test=^...!"
:: test=^...!
:: ! has no impact on ^ when delayed expansion is disabled
setlocal enableDelayedExpansion
set "test=^"
:: test=^
:: There is no ! on the line, so no need to escape the quoted ^.
set "test=^!"
:: test=!
set test=^^!
:: test=!
:: ! must be escaped, and then the unquoted escape must be escaped
set var=hello
set "test=!var! ^^ ^!"
:: test=hello ^ !
:: quoted ^ literal must be escaped because ! appears in line
set test=!var! ^^^^ ^^!
:: test=hello ^ !
:: The unquoted escape for the ^ literal must itself be escaped
:: The same is true for the ! literal
call set test=!var! ^^^^ ^^!
:: test=hello ^ !
:: Delayed expansion phase occurs in the 1st pass only
:: CALL doubling protects the unquoted ^ literal in the 2nd pass
call set "test=!var! ^^ ^!"
:: test=hello ^^ !
:: Again, there is no way to prevent the doubling of the quoted ^ literal
:: when it is passed through CALL
Run Code Online (Sandbox Code Playgroud)