我只是对Windows批处理中的插入符号转义的一个特定情况感到好奇:
请将以下代码保存为文件ttt.bat
,并在命令提示符下运行ttt.bat
,为什么我必须重复插入5个插入符号(或克拉?)字符^
使这个"no new line echo"诀窍有效吗?我只想在回显的字符串中放一个管道'|'
。
有一些关于Windows批处理转义的文档,但是出于案例研究的目的,你能解释一下这个例子中使用的每个插入字符的含义是什么吗?谢谢!
@echo off
SetLocal EnableDelayedExpansion
set foo=Hello world
set bar=Why why
echo|set /P=!foo! ^^^^^| !bar!
EndLocal
答案 0 :(得分:5)
很明显:-)
以下是different phases of the parser。
第一个重要阶段是特殊字符阶段,插入符号转义下一个字符,对^|&<>
个字符很重要。
该行将从
减少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
或者看看差异 setlocal EnableDelayedExpansion
echo "carets ^^^"
echo "carets ^^^" !