1700436221
1700436222
管道符号是两个命令之间的一道竖杠,简单而优雅。例如,要计算某个目录中的文件数量,可以将ls的输出(每个文件一行)用管道导向wc(计算行数)的输入。
1700436223
1700436224
$ ls | wc
1700436225
1700436226
1700436227
1700436228
1700436229
1700436230
不妨将程序看成一种过滤器,读取数据进来,以某种方式进行处理,然后输出结果。有时这样做非常自然,例如在程序中选择、改变或计数。但有时过滤器并不是一边读入一边输出,例如,sort命令在产生任何输出之前必须读完所有输入。但这无关紧要——把它打包成可以放入管道中的过滤器,仍然有其意义。
1700436231
1700436232
肯和丹尼斯仅用一晚时间就升级了系统中的每个命令。最大的改变是,在未输入文件名参数时,从标准输入流中读取数据。标准错误流stderr的创造也有其必要性。标准错误是独立的输出流:发送给它的错误信息被区隔在标准输出之外,因此不会进入管道。总的来说,这事不难——大多数程序只需要抛弃会扰乱管道的无关信息,并将错误报告发送到stderr即可。
1700436233
1700436234
管道带动了很多令我记忆深刻的创新。管道面世的确切日期没人记得,不过应该是在1972年下半年,因为它没有出现在手册的第2版(1972年6月),但在第3版(1973年2月)中出现了。
1700436235
1700436236
关于如何组合既有程序而不是写新程序来完成某项任务,Unix房间的每位成员都有好主意。我的点子是深挖who命令。who命令列出当前登录的所有用户。在大多数人都在自己的计算机上工作的今天,who这样的命令意义并不大,但由于分时的本质是多人共享同一台计算机,所以知道还有谁也在使用系统会很有帮助。who命令确实增加了社群感:你可以看到谁登录了系统。遇到问题时,即使大家都是深夜在家工作,也可以寻求对方帮助。
1700436237
1700436238
who命令为每个登录用户输出一行信息,grep查找符合特定模式的所有文本,wc统计行数,所以使用以下管道就能获知登录用户的状态。
1700436239
1700436240
who # 谁登录了? who | wc # 有多少人登录了? who | grep joe # 乔登录了吗? who | grep joe | wc # 乔登录过多少次?
1700436241
1700436242
1700436243
1700436244
1700436245
1700436246
要想了解管道提供了怎样的改进,请考虑在没有管道的情况下,使用I/O重定向到文件,最后一个任务(乔登录过多少次)将如何执行:
1700436247
1700436248
who >temp1 grep joe
temp2 wc
1700436249
1700436250
1700436251
1700436252
1700436253
1700436254
然后还得删除临时文件。有了管道,一行命令就能完成任务,而且不会产生临时文件。
1700436255
1700436256
肯最喜欢提到的管道范例是语音计算器。这个程序使用了鲍勃·莫里斯的dc计算器程序。肯的number程序将数字输出成单词(“127”变成了“one hundred and twenty seven”),speak程序读入文本并合成发音。肯在2019年接受采访时说:
1700436257
1700436258
“在dc程序中输入1 2 +,计算结果由管道导入number程序,然后再导入speak程序,speak程序就会说出‘four’。
1700436259
1700436260
(听众大笑)
1700436261
1700436262
“我数学一向不好。”
1700436263
1700436264
回头看来,管道是Unix的主要贡献之一。正如丹尼斯1984年在“The Evolution of the Unix Time-sharing System”(Unix分时系统的演进)一文中写到的那样:
1700436265
1700436266
“同样一些命令,以简单方式持续使用,构成了Unix管道,这恰恰是管道的天才之处。实在需要脑洞大开,才能看到这种可能性并创造出这个概念。”
1700436267
1700436268
1700436269
1700436270
[
上一页 ]
[ :1.700436221e+09 ]
[
下一页 ]