【问题标题】:What is the difference between using process substitution vs. a pipe?使用进程替换与管道有什么区别?
【发布时间】:2018-12-19 23:37:00
【问题描述】:

我在tee 信息页面中遇到了一个使用tee 实用程序的示例:

wget -O - http://example.com/dvd.iso | tee >(sha1sum > dvd.sha1) > dvd.iso

我查找了>(...) 语法,发现了一个叫做“进程替换”的东西。据我了解,它使进程看起来像另一个进程可以写入/附加其输出的文件。 (如果我在这一点上错了,请纠正我。)

这与管道有何不同? (|) 我看到在上面的例子中使用了一个管道——这只是一个优先级问题吗?还是有其他区别?

【问题讨论】:

    标签: bash pipe process-substitution


    【解决方案1】:

    这里没有任何好处,因为这行代码也可以这样写:

    wget -O - http://example.com/dvd.iso | tee dvd.iso | sha1sum > dvd.sha1
    

    当您需要与多个程序进行管道传输时,差异开始出现,因为这些不能纯粹用| 来表达。随意尝试:

    # Calculate 2+ checksums while also writing the file
    wget -O - http://example.com/dvd.iso | tee >(sha1sum > dvd.sha1) >(md5sum > dvd.md5) > dvd.iso
    
    # Accept input from two 'sort' processes at the same time
    comm -12 <(sort file1) <(sort file2)
    

    在您出于任何原因不能或不想使用管道的某些情况下,它们也很有用:

    # Start logging all error messages to file as well as disk
    # Pipes don't work because bash doesn't support it in this context
    exec 2> >(tee log.txt)
    ls doesntexist
    
    # Sum a column of numbers
    # Pipes don't work because they create a subshell
    sum=0
    while IFS= read -r num; do (( sum+=num )); done < <(curl http://example.com/list.txt)
    echo "$sum"
    
    # apt-get something with a generated config file
    # Pipes don't work because we want stdin available for user input
    apt-get install -c <(sed -e "s/%USER%/$USER/g" template.conf) mysql-server
    

    【讨论】:

    • 所以,这实际上就像是在说&gt; filename.ext&lt; filename.ext,但它是一个进程而不是一个文件?
    • 是的。 echo &lt;(date)cat &lt;(date) 提供了一个很好的线索来了解它是如何工作的。
    • 与重定向有一个重要区别:它不重定向任何内容,而是将管道名称(实际上类似于“/dev/fd/63”)作为参数传递给命令,并期望命令打开该“文件”并读/写它。 @thatotherguy 给出的echo &lt;(date) 示例应该显示这一点,因为它只是打印文件名而不是从中读取。
    猜你喜欢
    • 2018-08-25
    • 2021-05-08
    • 2013-09-05
    • 2020-03-21
    • 2015-02-02
    • 2021-08-10
    • 1970-01-01
    • 2010-09-16
    相关资源
    最近更新 更多