2016-03-05 75 views
12

什么是在Bash中创建非线性管道的最简洁,最简单,最高效,最短,最快,最简单,最优雅的方法?在Bash中创建非线性管道的最简洁方法是什么?

我有三个命令:mksockircloginircpingpong。我想管标准输入ircloginircpingpongmksock和管道mksock标准输出ircpingpong。这意味着mksockircpingpong处于循环状态。我画了一张图。 Diagram

irclogin只需要被运行一次,并成为第一输入到mksock。之后,ircpingpongstdin应随时接受。我目前使用的管道和临时文件是这样的:

#!/bin/bash 

server=127.0.0.1 
port=6667 

infifo=/tmp/ircin 
outfifo=/tmp/ircout 
pongfifo=/tmp/ircpong 

rm $infifo 
rm $outfifo 
rm $pongfifo 
mkfifo $infifo 
mkfifo $outfifo 
touch $pongfifo 

(irclogin | cat - $infifo & tail -f $pongfifo;) | mksock $server $port | tee $outfifo | stdbuf -oL ircpingpong > $pongfifo & 
cat < $outfifo & 
cat > $infifo 
pkill tail 

工作,但我想知道是否有更好的方法来做到这一点。它困扰我,我正在使用一个文件,而不是一个管道从循环回ircpingpongmksock使用尾巴。因为根据我的理解,在tail -f开始读取之前,管道上会写入一些东西,所以它错过了。同样困扰我的是,我必须在脚本结尾处杀死尾部,因为它并不会自行停止,并且即使在脚本结束后也会使套接字连接。

+2

这是Coproceses的用途。它们在Korn shell和bash上的支持不同,bash协处理器在bash 4.0中引入。请参阅http://wiki.bash-hackers.org/syntax/keywords/coproc – cdarke

回答

2

我可以建议没有临时文件版本,以及两个FIFO-S:

fifo1=/tmp/fifo1 
fifo2=/tmp/fifo2 
rm $fifo1 
rm $fifo2 
mkfifo $fifo1 
mkfifo $fifo2 

ircpingpong < $fifo1 > $fifo2 & 
(mksock <$fifo2|tee $fifo1)& 
irclogin >$fifo2 & 
cat >$fifo2 

的想法是独立运行的所有程序,只保证每个程序的输入和输出是否正确重定向根据此图:

pipe-flow

当然,ircpingpong必须阅读stdin和写入stdoutirclogin必须写入stdoutmksock必须从stdin读取并写入stdout