原文地址:Bash process substitution
对于像diff
这样可以接收多个文件作为参数的命令来说,如果能既可以接收文件作
为参数,又能接收其他命令的输出作为参数就再好不过了。举例来说,如果你想用命
令diff -u
来比较ps
与ps -e
的输出结果,一个简单的方法把它们的输出存入文
件,再分别比较:
1 | ps > ps.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 | ps -ef | tee >(awk '$1=="tom"' >toms-procs.txt) \ |
一般来说,只要在命令行中你可以指定文件的位置,都可以用这个语法来处理字符流。