有趣的问题:-)
CMD 处理从左到右的重定向。您想首先将 2 (stderr) 重定向到 &1 (stdout),然后将 1 (stdout) 重定向到其他东西。此时stderr仍将被重定向到之前的stdout定义。管道仍然可以使用标准输出的旧定义(现在包含标准错误)。
如果您不关心标准输出,那么您可以重定向到 nul
program.exe 2>&1 1>nul | find " "
如果要将标准输出捕获到文件,然后重定向到文件
program.exe 2>&1 1>yourFile | find " "
如果您仍想在控制台上看到标准输出,但您只想通过管道将标准错误传送到 FIND,那么您可以将 1 重定向到 con:
program.exe 2>&1 1>con: | find " "
请注意,stdout 和 con: 的原始定义之间存在细微差别。例如,cls >con:
不清除屏幕,而是在屏幕上打印一个有趣的字符。
如果您使用第三个(最初未使用的)文件句柄,则可以真正交换 stdout 和 stderr。1 和 3 将包含 stderr 的原始定义,2 将包含 stdout 的原始定义。
program.exe 3>&2 2>&1 1>&3 | find " "
实际上,每次执行重定向时都会定义一个额外的文件句柄。原始定义保存在第一个可用的未使用文件句柄中。假设在发出上述命令之前没有任何重定向。3>&2
不保存 3 的原始定义,因为 3 之前没有定义。但是2>&1
将stderr的原始定义保存在4中(3已经用过),1>&2
将stdout的原始定义保存在5中。
所以从技术上讲,不需要 3 的显式重定向来交换 stderr 和 stdout
program.exe 2>&1 1>&3 | find " "
2>&1
将 stderr 保存在 3 中,并将 2 重定向到 &1(stdout)。1>&3
将标准输出保存在 4 和 1 被重定向到 &3 (stderr)。
但是,只有在您确定在发出命令之前尚未定义 3 时,上述操作才能正常工作。在我之前的代码示例中明确定义 3 会更安全。
请参阅为什么我的 stderr 重定向在命令完成后没有结束?我该如何解决?对于一些非常疯狂的重定向冒险:-)