批处理脚本:为什么不在这种情况下重定向stdout工作?

Jam*_* Ko 4 windows powershell cmd batch-file command-prompt

如果打开命令提示符并键入以下内容:

echo foobar > nul
Run Code Online (Sandbox Code Playgroud)

因为nul吞下了所有的输入,它什么都不会打印出来.但是如果您使用PowerShell运行该命令:

powershell "echo foobar" > nul
Run Code Online (Sandbox Code Playgroud)

它将输出foobar到控制台.为什么会这样,我该怎么做才能解决它?

编辑: 是输出$PSVersionTable.看起来我正在使用PowerShell v5.0.

mkl*_*nt0 5

注意:我假设您从cmd.exe调用命令,而不是从PowerShell中调用,这与我看到的症状一致.

你偶然发现PS(PowerShell)v5中的一个错误( v3中没有出现;对问题的评论表明它也不在v4中),虽然我不完全理解为什么PS应该受到指责,因为我期待cmd.exe处理重定向.
但是,我可能会遗漏一些东西,所以请告诉我.

PowerShell 应该发送它所谓的成功流 - 默认输出的东西,包括与外部世界的标准输出echo的别名.Write-Output

在较旧的PS版本>NUL中,有效地抑制了PowerShell的输出.
奇怪的是,v5中错误只会影响NUL,而重定向到实际文件会起作用.

至于解决方法:

如果您的代码与v2兼容,请尝试以下操作:

powershell -version 2 "echo foobar" > NUL
Run Code Online (Sandbox Code Playgroud)

否则,重定向到实际文件并在之后删除该文件:

powershell "echo foobar" > "%TEMP%\NUL-bug-workaround" & del "%TEMP%\NUL-bug-workaround"
Run Code Online (Sandbox Code Playgroud)

  • 写入控制台时,PowerShell不使用*stdout*,而是使用[`WriteConsole`](https://msdn.microsoft.com/library/windows/desktop/ms687401.aspx).因此,如果被重定向,它需要特殊的逻辑来写入*stdout*.但是,似乎由于某种原因,PowerShell不使用`[Console] :: IsOutputRedirected`,而是使用它自己的逻辑,对于`> nul` case有缺陷. (2认同)
  • 对我来说,它看起来像一个bug.我想不出任何忽略重定向到'nul`的原因. (2认同)