为什么管道不能用于`python -V / java -version`等?

时间:2016-01-11 23:03:00

标签: pipe file-descriptor

今天我发现了一些有趣的东西。请先检查我的测试:

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...生成相同的命令。

我测试过:

  • tty + bash / zsh
  • Urxvt + bash / zsh
  • Xfce终端+ bash / zsh

测试结果相同。

我也测试了java -h| sed 's/[jJ]ava/----/',它也不起作用。但是python -h|sed 's/PYTHON/----/'有效。

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

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

如果有必要,我的测试机器的一些env./version信息:

  • bash 4.3.42
  • zsh 5.2
  • Linux 4.2.5-1(Archlinux)

1 个答案:

答案 0 :(得分:1)

简单地说,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)

所以,如果你想通过stdin上的管道发送它:

$ 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)