shell中的进程替换

2011-01-19  李卓华 

 在支持命名管道(FIFOs)或者'/dev/fd'的系统上可以实现Process Substitution,基本格式如下
    command <(list)
    or  
    command >(list)
    开始list的运行的时候会把list的输入输出连接到一个FIFO或者某个`/dev/fd'下的文件,而整个扩展的结果就是把这个文件的文 件名作为参数传递给命令command。如果使用>(list)的话,command写入这个文件的内容,就会作为list的输入。而如果使用<(list)的话, 那么list的输出就可以使command从这个文件中读到。注意<,>与左括号之间是没有空格的,否则的话会被解释成为重定向操作
    在允许的情况下 process substitution和parameter expansion, variable expasion, command expansion 和arithmatic expasion一起被执行.
     好处,能解决一些重定向不能解决的问题,如让一个命令有多个输入的情况:
有一个例子,要求将2个文件,a和b的内容进行查找,找到唯一的行,然后输出。下面是采用redirection的方法:
# sort a | uniq >tmp1
# sort b | uniq >tmp2
# comm -3 tmp1 tmp2
a
f
g
# rm tmp1 tmp2
如果使用process substitution,可以这样做:
# comm -3 <(sort a | uniq) <(sort b | uniq)
a
f
g
 这样明显效率提高了




 进程替换的概念: 进程替换命令替换很相似. 命令替换把一个命令的结果赋值给一个变量, 比如dir_contents=`ls -al`xref=$( grep word datafile). 进程替换把一个进程的输出提供给另一个进程(换句话说, 它把一个命令的结果发给了另一个命令).
   格式:

>(command)

<(command)

  进程替换需要放置在一个命令的文件参数的位置,比如diff file1 file2就可以使用进程替换,这样我们就不是比较两个文件了,而是比较两个进程的输出:

diff <(cmd1) <(cmd2)

  然而对于diff来说,她什么都不知道。

实现原理:cmd执行时,将其标准输出重定向到/dev/fd/n的一个文件,而diff就读取n这个文件描述符,即将其标准输入重定向到了/dev/fd/n。所以diff还以为他是通过文件读取的内容。

进程替换与命令替换的区别:

命令替换有:$(cmd) 或者 `cmd`区别是,命令替换直接将命令的结果放在这里,而进程替换是将结果写入一个文件,而其他命令去读取这个文件。命令替换一般用来将执行结果赋值给一个变量,而进程替换一般用来将运行结果交给另一个命令去执行但是不能使用管道pipe.即不使用subshell。

497°/4979 人阅读/0 条评论 发表评论

登录 后发表评论