为什么管道在 `python -V/java -version` 等上不起作用?

why the pipe doesn't work on `python -V/java -version` etc?

今天我发现了一件有趣的事。请先检查我的测试:

kent$  ruby --version
ruby 2.3.0p0 (2015-12-25 revision 53290) [x86_64-linux]

kent$  ruby --version|sed 's/ruby/----/'
---- 2.3.0p0 (2015-12-25 revision 53290) [x86_64-linux]

kent$  python -V                                                                                                  
Python 2.7.11

kent$  python -V|sed 's/Python/----/'   
Python 2.7.11

kent$  java -version
Picked up _JAVA_OPTIONS: -Dawt.useSystemAAFontSettings=on -Dswing.aatext=true
java version "1.8.0_66"
Java(TM) SE Runtime Environment (build 1.8.0_66-b17)
Java HotSpot(TM) 64-Bit Server VM (build 25.66-b17, mixed mode)

kent$  java -version|sed 's/[jJ]ava/----/'
java version "1.8.0_66"
Java(TM) SE Runtime Environment (build 1.8.0_66-b17)
Java HotSpot(TM) 64-Bit Server VM (build 25.66-b17, mixed mode)

正如你在上面看到的,我想对命令的输出进行文本处理(检查 python、ruby、java 的版本信息的输出)

sed 很简单,但只有 ruby --version 有效。我尝试用其他 linux 常用命令替换 sed,例如 awk, grep... 结果相同。

我测试过:

测试结果相同

我也测试了java -h| sed 's/[jJ]ava/----/',也没用。然而 python -h|sed 's/PYTHON/----/' 有效。

我认为这些输出是标准输出,在 pipe 之后,它将是 stdin 并且应该被以下命令接受为输入...但看来我错了。

有人可以解释为什么会这样吗?

如果需要的话,我的测试机的一些环境/版本信息:

简单地说,java 正在 stderr 上打印其输出。例如:

$ java -version > /dev/null
java version "1.7.0_91"
OpenJDK Runtime Environment (IcedTea 2.6.3) (7u91-2.6.3-0ubuntu0.15.10.1)
OpenJDK 64-Bit Server VM (build 24.91-b01, mixed mode)

因此,如果您想通过标准输入上的管道发送它:

$ java -version 2>&1 |sed 's/[jJ]ava/----/'
---- version "1.7.0_91"
OpenJDK Runtime Environment (IcedTea 2.6.3) (7u91-2.6.3-0ubuntu0.15.10.1)
OpenJDK 64-Bit Server VM (build 24.91-b01, mixed mode)