4.6 将一个命令的输出用作另一个命令的输入
|
Unix是由一些小片段松散连接在一起的,这是句真理。除了管道(pipe)的概念,没有什么比它更能体现这一原则了。管道就是键盘上的“|
”符号,当把它放在两个命令之间时,它可以将第一个命令的输出作为第二个命令的输入。换句话说,|
重定向stdout,将它发送到第二个命令的stdin。
下面用一个简单的例子来帮助你更好地理解这个概念。ls
命令是我们早已知道的,在第5章中还将讲述less
命令。现在只需要知道less命令能够让用户在屏幕一次查看文本文件的一页。如果在包含很多文件的目录上运行ls
命令,例如/usr/bin
,显示内容就会因为速度太快而不能阅读。但是如果将ls
命令的输出通过管道发送给less
命令,就可以在屏幕以一次阅读一页的方式来查看结果了。
$ pwd
/usr/bin
$ ls -1
zipinfo
zipnote
zipsplit
zsoelim
zxpdf
[Listing truncated due to length - 2318 lines!]
$ ls -1 | less
411toppm
7z
7za
822-date
a2p
通过管道将ls -1
的结果传递给less
,就可以一次在屏幕上只查看结果的一页,这样用起来要容易得多。
接下来是一个更高级的例子,使用了两个后面将会讨论的命令ps
和grep
。第12章将介绍ps
命令,它能够列出正在运行的进程;第9章介绍grep
命令,可以用它查找文件中与指定模式相匹配的行。假设Firefox运行异常,你怀疑后台仍旧有多个Firefox程序的副本在运行。ps
命令会列出计算机中正在运行的所有进程,但是输出的结果总是很长,而且还在不断地变化。如果将ps
的输出通过管道传递给grep
命令,让它去搜索firefox,这样,Firefox确实还在运行的话,你就能够马上做出判断了。
说明 为了节约篇幅,在以下代码中删除了所有者的信息,每个实例的所有者都是同一个用户。
$ ps ux
1504 0.8 4.4 75164 46124 ? S Nov20 1:19 kontact
19003 0.0 0.1 3376 1812 pts/4 S+ 00:02 0:00 ssh
➥admin@david.hartley.com
21176 0.0 0.0 0 0 ? Z 00:14 0:00
➥[wine-preloader] <defunct>
24953 0.4 3.3 51856 34140 ? S 00:33 0:08 kdeinit:
➥kword /home/scott/documents/clientele/current
[Listing truncated for length]
$ ps ux | grep firefox
scott 8272 4.7 10.9 184072 112704 ? Sl Nov19 76:45
➥/opt/firefox/firefox-bin
将原本有58行的输出结果变成了一行,现在读起来容易多了。
说明 要记住,虽然很多程序都能够用管道,但并非所有程序都如此。例如,文本编辑器vim(或pico、nano及emacs)会接管整个shell,因此,键盘的所有输入都直接发送给vim,而所有输出都在程序的某个位置进行显示。因为vim完全控制着shell,所以也就不能使用程序通过管道重定向它的输出。多使用几次shell,你就能逐渐学会如何识别不能使用管道的程序了。