有没有办法将仅标准错误输出重定向到标准输出(而不是合并两者),以便可以将其导入其他程序?

24 浏览
0 Comments

有没有办法将仅标准错误输出重定向到标准输出(而不是合并两者),以便可以将其导入其他程序?

我在Windows的CMD.EXE环境中工作,想要将stdout的输出与stderr的输出保持一致,这样我就可以将错误消息直接传输给其他程序,而不需要通过文件中转。

我知道2>&1的表示方法,但它会将stdoutstderr合并为一个流。

我想的是这样的:

program.exe 2>&1 | find " "

但这样做会像下面这样将stdout和stderr合并:

program.exe | find " " 2>&1

我意识到我可以这样做...

program 2>file
type file | find " "
del file

但这样做没有program | find " "这种表示法的灵活性和强大功能。这样做要求在处理输出之前program已经完成了输出。

0
0 Comments

从上述链接中查看,你想要的是 `2>&1 1>NUL`。所以下面的代码对你应该适用:

`test.exe 2>&1 1>NUL | find "someErrorString"`

0
0 Comments

在CMD中,重定向的处理是从左到右的。首先,将2(stderr)重定向到&1(stdout),然后将1(stdout)重定向到其他地方。此时,stderr仍然会被重定向到stdout的前一个定义中。管道仍然可以使用旧的stdout的定义(现在包含stderr)。

如果不关心stdout,可以将其重定向到nul:

program.exe 2>&1 1>nul | find " "

如果想要将stdout捕获到文件中,则将其重定向到文件:

program.exe 2>&1 1>yourFile | find " "

如果仍然希望在控制台上看到stdout,但只想将stderr管道传递给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将stdout保存在4中,并将1重定向到&3(stderr)。

但是,上述方法只有在确保在发出命令之前未定义3时才能正常工作。在我之前的代码示例中,显式定义3更加安全。

对于重定向的更多详细信息,请参阅Why doesn't my stderr redirection end after command finishes? And how do I fix it?

- 添加了另一种比使用con更可靠的选项:

但是对我来说,3>&2 2>&1 1>&32>&1 1>&3都会将stdout和stderr合并。

- 真的吗?对我来说,在Vista和Windows 7上都可以正常工作。我还没有机会在XP上检查。DIR DoesNotExist 2>&1 1>&3 | FIND ""将空目录列表传递到屏幕,但会删除错误消息,而DIR DoesNotExist 2>&1 1>&3 | FIND /V ""同时传递空目录列表和错误消息。

DIR DoesNotExist 2>&1 1>&3 | FIND ""会删除错误消息,而... | find " "会显示两者。我原以为DIR DoesNotExist 2>&1 1>&3DIR DoesNotExist 2>&1 1>&3 | find " "是相同的,因为DIR DoesNotExist 2>&1 1>nul可以工作。此外,我不确定为什么stderr等于"",所以我不明白... | find ""是如何工作的(我使用的是Windows 7 Ultimate x64)。

- 我认为你的问题可能是你的测试有问题。... | FIND " "将匹配任何包含空格的行。... | FIND /V ""是FIND的一个怪癖,它匹配所有行,我从未理解为什么,但它很有用。... | FIND ""不会匹配任何行。我选择这些形式是为了验证stderr是否被传递而stdout不被传递。

奇怪。现在我对重定向的工作原理更加了解了,再次感谢!

0