Dos/Windows 批处理插入符号转义在设置 /P 提示符下



我只是对 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 ^^^" !

最新更新