如何在bash脚本中fork / pipe stdin?

时间:2016-09-29 00:04:03

标签: bash pipe stdin

我有一个我希望以

运行的脚本
$ myscript < mydata.dat

myscript内我需要将STDIN分叉/管道到多个目的地

#!/usr/bin/env bash

php script1.php > out1
php script2.php > out2
php script3.php > out3

每个人都需要一份STDIN。有可能吗?

这样的东西
# obviously this is broken ...
STDIN | php script1.php > out1
STDIN | php script2.php > out2
STDIN | php script3.php > out3

2 个答案:

答案 0 :(得分:7)

要将stdin复制到多个流程,请使用ViewChild流程替换

tee

构造tee >(script1 > out1) >(script2 >out2) ... | lastscript >outlast 称为流程替换。它创建了一个>(...)可以写入的类文件对象。 parens中的命令被执行,并且对它的任何tee写入都以stdin的形式提供给命令。

bash,ksh和zsh支持

进程替换。它不是POSIX,不会在短划线下工作。

简单示例

让我们考虑一下这个简单的脚本:

tee

我们可以运行它并验证结果:

$ cat myscript 
#!/bin/bash
tee >(grep 1 >out1) >(grep 2 >out2) | grep 3 >out3

答案 1 :(得分:2)

John1024答案的变体是使用命名管道代替过程替换。

mkfifo p1 p2 p3
tee p1 p2 p3 > /dev/null & # or tee p1 p2 > p3 &
php script1 < p1 > out1 &
php script2 < p2 > out2 &
php script2 < p3 > out3 &
wait
rm p1 p2 p3

(进程替换是有效的,在某些实现中,字面上是对创建,管理和清理显式命名管道的语法支持。)