为什么“java -version”将其输出打印到错误流?

时间:2014-05-05 04:42:55

标签: java

让我们尝试重定向java的标准错误:

java -version 2> ~/error.txt

error.txt填充了版本。

让我们尝试重定向标准输出:

java -version > ~/output.txt

output.txt为空。

为什么java二进制打印正常输出到错误流?

2 个答案:

答案 0 :(得分:9)

根据the Java documentation

  

-showversion

     

显示版本信息并继续执行应用程序。此选项等同于-version选项,但后者指示JVM在显示版本信息后退出。

     

-version

     

显示版本信息,然后退出。此选项等同于-showversion选项,除了后者在显示版本信息后不指示JVM退出。

现在考虑Wikipedia's definition of stderr

  

标准错误是程序通常用于输出错误消息或诊断的另一个输出流。

大多数以POSIX为中心的工具都为其stdout流规定了非常谨慎的规范,因此工具的输出可以在其他地方输出。 Stderr的规定要少得多,并且可以自由地用于记录和错误。

使用-showversion,Java允许在正在运行的应用程序旁边打印版本信息。但是,如果版本信息打印到stdout,则它与可能附带的正常应用程序输出无法区分,从而迫使您自己扫描并删除该行输出。当然,使用-version代替-showversion,版本字符串很可能预期输出,但保持一致性本身就是一个不错的目的。

对于它的价值,printing requested metadata to stderr vs stdout is something of an open question,除了每个应用程序记录的行为之外,在“标准实践”方面几乎没有。

要解决此问题,只需将stderr重定向到stdout:

VERSION=$(java -version 2>&1)

答案 1 :(得分:1)

看起来像是一个bug或只是一个不一致的java命令与UNIX中的许多其他命令相比发送版本输出到stdout:

mvn -v > ~/output.txt # works as expected

There is a bug因为它已经关闭了。可能Oracle无法修复该问题,因为它可能会导致系统出现问题,而这些系统可能会以这种方式运行。