使用流程替换与管道之间有什么区别?

时间:2018-07-11 20:32:17

标签: bash pipe process-substitution

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

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

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

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

1 个答案:

答案 0 :(得分:7)

这里没有任何好处,因为该行同样可以这样写:

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