[译]Bash 进程替换(process substitution)

原文地址:Bash process substitution

对于像diff这样可以接收多个文件作为参数的命令来说,如果能既可以接收文件作
为参数,又能接收其他命令的输出作为参数就再好不过了。举例来说,如果你想用命
diff -u来比较psps -e的输出结果,一个简单的方法把它们的输出存入文
件,再分别比较:

1
2
3
$ ps > ps.out
$ ps -e > pse.out
$ diff -u ps.out pse.out

这样当然可以工作,不过 Bash 提供了一个更简便的方法叫做进程替换(process
substitution),它让你可以把命令的标准输出当作文件来用。操作符的形式就是
<()>()。在我们的例子中,我们想把两个命令的标准输出重定向为文件:

1
$ diff -u <(ps) <(ps -e)

这在功能上是相等的,只是没有了临时文件而更整洁。这个方法对于跨服务器比较文
件也很方便,比如使用ssh

1
$ diff -u .bashrc <(ssh remote cat .bashrc)

相应地,你也可以用>()将一个本应是文件名的位置定向到另一个命令的标准输入。
这个特性对向日志之类的文设置件即时过滤很方便。下面的例子中,我调用了rsync
指定它将自己的动作保存到log.txt中,但在保存之前会通过grep -vF .tmp命令
去除所有匹配到.tmp的内容:

1
$ rsync -arv --log-file=>(grep -vF .tmp >log.txt) src/ host::dst/

把这个语法同tee结合起来是模拟对stdout进行多个筛选的一种方法,将一个命令
的输出通过你想用的各种方式进行转换:

1
2
3
4
$ ps -ef | tee >(awk '$1=="tom"' >toms-procs.txt) \
>(awk '$1=="root"' >roots-procs.txt) \
>(awk '$1=="httpd"' >not-apache-procs.txt) \
>(awk 'NR>1{print $1}' >pids-only.txt)

一般来说,只要在命令行中你可以指定文件的位置,都可以用这个语法来处理字符流。

0%