「Shell」- 进程替换(Process substitution)

  CREATED BY JENKINSBOT

什么是进程替换

先看WIKI的解释:

	In computing, process substitution is a form of inter-process communication that allows the input or output of a command to appear as a file.
	在计算中,进程替换是进程间通信的一种形式,允许命令的输入或输出作为文件出现。

进程替换的语法

cmd1 >(cmd2)

	将cmd1输出发送给cmd2

cmd1 <(cmd2)

	将cmd2的输出发送给cmd1

在这里:>(cmd2)或者<(cmd2)等价于一个内容为cmd2输出的文件。这么说可能不明白,请看下面“进程替换的机制”。

进程替换的机制

题外话: 如果你不会英语,你真的会错过很多东西。

进程替换的实现有两种:

	* 在支持/dev/fd的系统上(大多数都支持),通过pipe()系统调用实现。pipe()系统调用会为匿名管道返回一个文件描述符$fd,然后用字符串/dev/fd/$fd替换命令行上的>(cmd2)或者<(cmd2)。
	* 对于不支持/dev/fd的系统上,Bash使用新临时文件名调用mkfifo来创建一个命名管道,然后使用此文件名作为替代。

为了演示所涉及的步骤,思考如下命令:

	diff file1 <(sort file2)

shell的执行步骤如下(对于支持/dev/fd的系统):

	* 创建一个新的匿名管道。这个管道可以通过像/dev/fd/63这样的东西访问;你可以用**echo <(true)**命令看到它。
	* 在后台执行替代命令(当前为sort file2),将输出输送到匿名管道。
	* 执行主命令,使用匿名管道的路径替换替带命令。在这个例子中,完整的命令可能扩展为:diff file1 [[/dev/fd/63]]
	* 当执行结束时,关闭匿名管道。

对于命名管道(不支持/dev/fd的系统),唯一不同的地方在于管道的创建和删除:使用mkfifo创建;使用unlink删除。其他方面一样的。

进程替换的示例

#!/bin/sh

echo <(ls)

# 输出:
# /dev/fd/63

对于cmd1 >(cmd2),当Bash在执行进程替换的时候,Bash会将cmd2的标准输出

参考文献

http://teliute.org/linux/abs-3.9.1/process-sub.html
https://en.wikipedia.org/wiki/Process_substitution