如何在 bash 脚本中 fork/pipe stdin?
How to fork/pipe stdin in bash script?
我有一个脚本想要运行作为
$ myscript < mydata.dat
内部 myscript
我需要 fork/pipe 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
要将标准输入复制到多个进程,请使用 tee
和 进程替换:
tee >(script1 > out1) >(script2 >out2) ... | lastscript >outlast
构造 >(...)
称为 进程替换 。它创建一个 tee
可以写入的类文件对象。 parens 中的命令被执行,tee
写入的任何内容都作为标准输入提供给命令。
进程替换 受bash、ksh 和zsh 支持。它不是 POSIX 并且不会在破折号下工作。
简单示例
让我们考虑一下这个简单的脚本:
$ cat myscript
#!/bin/bash
tee >(grep 1 >out1) >(grep 2 >out2) | grep 3 >out3
我们可以运行它并验证结果:
$ seq 10 | bash myscript
$ cat out1
1
10
$ cat out2
2
$ cat out3
3
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
(进程替换是有效的,在某些实现中字面意思是对创建、管理和清理显式命名管道的语法支持。)
我有一个脚本想要运行作为
$ myscript < mydata.dat
内部 myscript
我需要 fork/pipe 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
要将标准输入复制到多个进程,请使用 tee
和 进程替换:
tee >(script1 > out1) >(script2 >out2) ... | lastscript >outlast
构造 >(...)
称为 进程替换 。它创建一个 tee
可以写入的类文件对象。 parens 中的命令被执行,tee
写入的任何内容都作为标准输入提供给命令。
进程替换 受bash、ksh 和zsh 支持。它不是 POSIX 并且不会在破折号下工作。
简单示例
让我们考虑一下这个简单的脚本:
$ cat myscript
#!/bin/bash
tee >(grep 1 >out1) >(grep 2 >out2) | grep 3 >out3
我们可以运行它并验证结果:
$ seq 10 | bash myscript
$ cat out1
1
10
$ cat out2
2
$ cat out3
3
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
(进程替换是有效的,在某些实现中字面意思是对创建、管理和清理显式命名管道的语法支持。)