Stream 3 句柄重定向导致输出溢出

Stream 3 handle redirection causes output flood

当这个命令

时我正在玩wmic
wmic<nul 3>nul

产生了这个:

奇怪的是,任何命令都可以,但只有流3导致输出泛滥。
我在 SO "cmd output flood" 上进行了谷歌搜索,但找不到任何重复项或任何结果。
问题:为什么只有流 3 有效?

更新:同样,

>con 3<con :

完全禁用STDOUT!

我认为, by aschipfl, to 解释了问题的根源。

请参考他们的内部细节,这个答案只是一个总结来解释不同的行为。

  • 创建重定向时,cmd 中处理此任务的代码会尝试避免将原始句柄保存到正在重定向的流中的问题,以便可以恢复重定向过程。

  • 但是使用的函数(标准 _dup())的工作方式和创建重定向时使用的顺序可以改变内部结构,最终代码反转重定向使用了错误的信息。

简而言之:

<nul 3<nul wmic
  • <nulstdin 句柄保存在 &3 并将 nul 流分配给 &0
  • 3<nul&3 里面的句柄保存到 &4 并将 nul 流分配给 &3
  • wmic 被执行。因为它正在从 nul(分配给 &0)读取,所以它无法读取任何内容并结束。
  • &0&3 的保存位置恢复,但现在 &3 指向 nul
  • &3&4 恢复。现在它指向原来的 stdin

在最初的 achipfl 问题中,观察到的行为是命令提示符关闭。代码执行后

< file1 3< file2 echo/

重定向取消进程使 stdin 流指向磁盘文件 (file2)。 cmd 开始读取此文件以执行命令(通常从 stdin 开始执行),在文件末尾读取操作失败并且 cmd 实例结束。如果你想以一种复杂的方式看到它在工作中启动记事本,你可以尝试

( >file1 echo notepad ) & ( <nul 3<file1 break )

但在这个问题中,行为是不同的,因为分配给 &3 的流,一旦恢复重定向,将被复制到 stdin,它不是磁盘文件,而是 nul

<nul 3<nul echo/
  1. 执行命令并恢复重定向后 stdin 流与 nul 设备相关联
  2. cmd 显示提示并尝试检索从 nul
  3. 读取的新命令
  4. 读取操作结束但未检索任何内容,因此cmd不执行任何内容
  5. 转到 2

问题“为什么只有流 3 有效?”(从某种意义上说它无效 ;))是不正确的。你可以做类似

1>file1 <nul 4<nul echo/

并使用不同的流获得相同的结果。或者你可以做

 3<nul <nul echo/

它会起作用(在它起作用的意义上)。

您请求流重定向的顺序、cmd 内部代码如何处理它们以及是否存在仍处于活动状态的先前重定向可以决定命令的成功或失败。