test.bat的内容是:
setlocal EnableExtensions EnableDelayedExpansion
set param1=%~1
echo %param1%
有人可以解释为什么test.bat "^^!^^^&^^^^"
会导致cmd窗口崩溃,但test.bat "^^^&^^^^"
会将&^
设置为变量param1吗?
我可以test.bat "pass^^!word"
我得到pass!word的预期结果。
更新:test.bat "^^!^^^^^&^^^^^^^^"
有效。但我不完全确定原因。这被解释为set param1=^!^^&^^^^
。为什么^在它前面需要^^^?
答案 0 :(得分:2)
你遇到了很多问题,因为在你的情况下会对你的特殊字符进行多次评估。
首先在set
命令中,特殊字符阶段会将字符串"^^!^^^&^^^^"
减少为
^!^&^^
但是,由于启用了延迟扩展并且您的字符串包含感叹号,因此
将启用另一个阶段以再次减少插入符号。
!&^
此时param1
包含!&^
,您可以使用set param1
但是当您尝试使用echo %param1%
回显该值时,将执行另一次扩展
现在您遇到了问题,因为%param1%
会扩展为!&^
,
感叹号将被删除,因为扩展变量时缺少第二个感叹号,
&符号将被视为新命令分隔符和
结尾插入符号将被视为多行字符
echo ! & ^<next line>
在这里使用延迟扩展更加安全,因为这永远不会改变内容,因为这个阶段是解析器的最后一个。
setlocal EnableDelayedExpansion
set param1=%~1
set param1
echo !param1!
所有这些解释都可以在How does CMD.EXE parse scripts?
找到答案 1 :(得分:1)
这是因为Windows shell的转义字符是^,所以:
“^^ ^^^^^&安培;!^^^^^^^^”
每个^^变成^
每个^&amp;成为&amp;
所以最后你会得到:
“!^ ^^&安培; ^^^^”