http://zh.wikipedia.org/wiki/%E7%AE%A1%E9%81%93_%28Unix%29
在类Unix操作系统(以及一些扩展,Windows)中,管道(英语:Pipeline)是原始的软件管道:即是一个由标准输入输出链接起来的进程集合,所以每一个进程的输出(stdout)被直接作为下一个进程的输入(stdin)。 每一个链接都由未命名管道实现。过滤程序经常被用于这种设置。
这个概念是由道格拉斯·麦克罗伊为Unix 命令行发明的,命名用于比喻物理的管道。
所有广泛应用于UNIX和Windows中的shell程序都有特殊的语法构建管线。典型语法是使用ASCII中的垂直线“|”(正是由于这个原因,这个符号常被称为管道符)。当出现这样的语法时shell会启动各个进程,并调整各个进程的标准流之间的连接(还包括安排一些缓存)。
通常,管线中的进程的标准错误流("stderr")不会通过管道传输;它们被合并输出到控制台。然而,很多Shell提供一些扩充的语法去改变这一行为。比如在csh Shell和bash中,, 使用“|&”代替“|”来表示错误流也需要被合并进入标准输出,并传递给下一个进程。Bourne shell也可以合并错误流,通过 2>&1 也可以将错误流重定向到一个不同的文件。
在一些常用的简单管线中,shell仅仅只是用管道来连接每个子进程,然后在子进程中执行外部命令。因此shell本身没有通过管线来处理数据。
然而,shell也有可能直接处理管线数据。构建这样的语法像这样:
command | while read var1 var2 ...; do # process each line, using variables as parsed into $var1, $var2, etc # (note that this is a subshell: var1, var2 etc will not be available # after the while loop terminates) done
... 这样的语法叫 "pipemill" 。
使用C语言在UNIX中使用pipe(2)系统调用时,这个函数会让系统构建一个匿名管道,这样在进程中就打开了两个新的,打开的文件描述符:一个只读端和一个只写端。管道的两端是两个普通的,匿名的文件描述符,这就让其他进程无法连接该管道。 为了避免死锁并利用进程的并行运行的好处,有一个或多个管道的UNIX进程通常会调用fork(2)
产生新进程。并且每个子进程在开始读或写管道之前都会关掉不会用到的管道端。或者进程会产生一个子线程并使用管道来让线程进行数据交换。
在大多数类UNIX操作系统中,管线上的所有进程同时启动,输入输出流也已经被正确地连接,并且这些进程被调度程序所管理。最为重要的一点就是,所有的UNIX管道和其他管道实现不一样的地方就是缓存的概念:输出进程可能会以每秒5000 byte的速度输出,但是接收进程也许每秒只能接收100 byte,但不会有数据丢失。原因就是管道上游的进程的所有输出都会被放入一个队列中。当下游进程开始接收数据时,操作系统就会将数据从队列传至接收进程,并将传完的数据从队列中移除。当缓存队列空间不足时,上游进程会被终止,直到接收进程读取数据为上游进程腾出空间。在Linux中,缓存队列的大小是65536 byte。
根据Unix哲学——“一切都是文件”,netcat
和socat
这样的工具可以将管道连接到TCP/IP套接字。
管道的概念以及垂直线的记号(|)都是由道格拉斯·麦克罗伊发明的,他是早期命令行外壳的作者。他发现他常常将一个程序的输出作为另一个程序的输入,于是便发明了“管道。它的想法在1973年被实现,Ken Thompson将管道添加到了UNIX操作系统。[1]这个点子最终被移植到了其他的操作系统,比如DOS、OS/2、Microsoft Windows和BeOS,而且常常使用相同的记号(垂直线)。
虽然管道概念是独立发展的,但是 Unix 管道相似于、也确实晚于由Ken Lochner在20世纪60年代为Dartmouth Time Sharing System开发的'communication files'。[2][3]
在苹果Automator(类似管道一样将多个重复的命令链接起来)的那个机器人拿着一根管子的图标也是对于最初Unix管道概念的纪念。
主条目:管道 (软件)
其他操作系统的这个特色源自于Unix,例如 Taos 和 MS-DOS,最终成为软件工程的管道与过滤器设计样本
In Unix-like computer operating systems (and, to some extent, Microsoft Windows), a pipeline is a set of processes chained by their standard streams, so that the output of each process (stdout) feeds directly as input (stdin) to the next one. Filter programs are often used in this configuration.
The concept of pipelines was invented by Douglas McIlroy at Unix's ancestral home of Bell Labs, prior to the actual invention of the operating system, and implemented in Unix at his insistence, shaping its toolbox philosophy.[1][2] It is named by analogy to a physical pipeline. The standard shell syntax for pipelines is to list multiple programs to invoke in one command, separated by vertical bars:
program1 | program2 | program3
Each program is assumed to take input and give output on its standard streams. Each "|" tells the shell to connect the standard output of the left program to the standard input of the right program by an inter-process communication mechanism called an (anonymous) pipe, implemented in the operating system. Since pipes are unidirectional, data flows through the pipeline from left to right.
For example, to list (ls) files in the current directory, retain only the lines of ls output containing the string key (grep), and view the result in a scrolling page (less), one can issue the command