我只是对 Windows 批处理中插入符号转义的一个特定情况感到好奇:
请将以下代码另存为文件ttt.bat
,并在命令提示符下运行ttt.bat
,为什么我必须重复 5 次插入符号(或克拉^
?我只想在回声弦中放一个管'|'
。
有一些关于 Windows 批处理转义内容的文档,但出于案例研究目的,您能否解释此示例中使用的每个插入符号的含义是什么?谢谢!
@echo off
SetLocal EnableDelayedExpansion
set foo=Hello world
set bar=Why why
echo|set /P=!foo! ^^^^^| !bar!
EndLocal
很明显:-)
以下是所涉及的解析器的不同阶段。
第一个重要阶段是特殊字符阶段,插入符号转义下一个字符,对^|&<>
字符很重要。
该线路将从
echo|set /P=!foo! ^^^^^| !bar!
自
echo|set /P=!foo! ^^| !bar!
当一个插入符号逃逸下一个插入符号时,最后一个插入符号从管道中逸出。
这里的下一个重要阶段是延迟扩展阶段,该阶段仅在至少一个!
在线路中时才出现。
在此阶段,插入符号也会转义下一个字符,但这里只需要插入符号本身和!
,在此阶段,延迟变量被扩展。
从
echo|set /P=!foo! ^^| !bar!
自
echo|set /P=Hello world ^| Why why
当您在此处使用管道时,管道的两侧都将传输到新的cmd.exe进程,并且命令将再次解析。
cmd.exe /c "echo"
和cmd /c "set /P=Hello world ^| Why why
现在只有set /P=Hello world ^| Why why
是相关的。
同样在特殊字符阶段,一个插入符号转义管道字符到
set /P=Hello world | Why why
延迟扩展阶段不会中断,首先是因为在新cmd中禁用了延迟扩展.exe(默认情况下),其次是因为行中没有任何!
。
就这样!
顺便说一句。
这里不需要生成两个进程,重定向更简单、更快捷
<nul set /P=!foo! ^^^| !bar!
没有延迟扩展,您只需要一个插入符号
<nul set /P=FOO ^| BAR
还是看看区别设置本地启用延迟扩展
echo "carets ^^^"
echo "carets ^^^" !