4.6 将一个命令的输出用作另一个命令的输入

|

Unix是由一些小片段松散连接在一起的,这是句真理。除了管道(pipe)的概念,没有什么比它更能体现这一原则了。管道就是键盘上的“|”符号,当把它放在两个命令之间时,它可以将第一个命令的输出作为第二个命令的输入。换句话说,|重定向stdout,将它发送到第二个命令的stdin。

下面用一个简单的例子来帮助你更好地理解这个概念。ls命令是我们早已知道的,在第5章中还将讲述less命令。现在只需要知道less命令能够让用户在屏幕一次查看文本文件的一页。如果在包含很多文件的目录上运行ls命令,例如/usr/bin,显示内容就会因为速度太快而不能阅读。但是如果将ls命令的输出通过管道发送给less命令,就可以在屏幕以一次阅读一页的方式来查看结果了。

  1. $ pwd
  2. /usr/bin
  3. $ ls -1
  4. zipinfo
  5. zipnote
  6. zipsplit
  7. zsoelim
  8. zxpdf
  9. [Listing truncated due to length - 2318 lines!]
  10. $ ls -1 | less
  11. 411toppm
  12. 7z
  13. 7za
  14. 822-date
  15. a2p

通过管道将ls -1的结果传递给less,就可以一次在屏幕上只查看结果的一页,这样用起来要容易得多。

接下来是一个更高级的例子,使用了两个后面将会讨论的命令psgrep。第12章将介绍ps命令,它能够列出正在运行的进程;第9章介绍grep命令,可以用它查找文件中与指定模式相匹配的行。假设Firefox运行异常,你怀疑后台仍旧有多个Firefox程序的副本在运行。ps命令会列出计算机中正在运行的所有进程,但是输出的结果总是很长,而且还在不断地变化。如果将ps的输出通过管道传递给grep命令,让它去搜索firefox,这样,Firefox确实还在运行的话,你就能够马上做出判断了。

说明 为了节约篇幅,在以下代码中删除了所有者的信息,每个实例的所有者都是同一个用户。

  1. $ ps ux
  2. 1504 0.8 4.4 75164 46124 ? S Nov20 1:19 kontact
  3. 19003 0.0 0.1 3376 1812 pts/4 S+ 00:02 0:00 ssh
  4. admin@david.hartley.com
  5. 21176 0.0 0.0 0 0 ? Z 00:14 0:00
  6. ➥[wine-preloader] <defunct>
  7. 24953 0.4 3.3 51856 34140 ? S 00:33 0:08 kdeinit:
  8. kword /home/scott/documents/clientele/current
  9. [Listing truncated for length]
  10. $ ps ux | grep firefox
  11. scott 8272 4.7 10.9 184072 112704 ? Sl Nov19 76:45
  12. ➥/opt/firefox/firefox-bin

将原本有58行的输出结果变成了一行,现在读起来容易多了。

说明 要记住,虽然很多程序都能够用管道,但并非所有程序都如此。例如,文本编辑器vim(或pico、nano及emacs)会接管整个shell,因此,键盘的所有输入都直接发送给vim,而所有输出都在程序的某个位置进行显示。因为vim完全控制着shell,所以也就不能使用程序通过管道重定向它的输出。多使用几次shell,你就能逐渐学会如何识别不能使用管道的程序了。