Windows上使用管道符号的echo命令的行为是什么?

4
我想要创建一个批处理文件,通过命令行参数传递变量名来打印变量的值,例如:
print.bat username

print.bat的内容如下:

@echo off
setlocal
set v=%%%1%%%
echo | echo %v%

虽然脚本运行完美,但我仍然不理解其工作原理。

echo | echo %v%

我理解的管道是将第一个命令的输出(也就是管道符左侧的命令)传递给第二个命令(也就是管道符右侧的命令),因此按照这种方式,正确的方式应该是echo %v% | echo(但它不起作用)。

有人可以解释一下这种行为吗?

谢谢


1
回声不读取标准输入。无论如何,你为什么认为需要将空回声管道到另一个回声命令中?也许你想做的是:echo.&echo %v% ?? - Squashman
@Squashman - 看起来它的行为像是 call,这非常奇怪,因为我也不会期望 echo 接受管道输入。 - SomethingDark
1个回答

7
set v=%%%1%%%

%1 是命令行中传递的第一个参数,在你的例子中是 username。当解析该行时,%% 被减半,结尾的单独的 % 被丢弃,最终将 v 设置为 %username%

echo | echo %v%
echo %v%被解释为echo %username%,但管道符号强制它在解释器的第二个实例中执行,在那里它经历了另一轮解析,将%username%扩展为username环境变量的值。

正确的方式应该是echo %v% | echo(这种方式不起作用)

由于echo不使用标准输入流,因此这样做无法实现。第一个echo %v%命令的输出被丢弃,第二个echo找不到命令行参数,因此打印出通常的ECHO is on
关键点在于echo | echo %v%中的第一个echo实际上并未真正用作echo。它的唯一作用是允许管道符号,从而导致重新解析第二个echo命令。type nul | echo %v%同样有效。
然而,这可以更廉价地通过使用call来完成。
@echo off
setlocal
set "v=%%%1%%"
call echo %v%

1
感谢您提供详细的答案和更优化的解决方案。 - Waqas Ali

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接