【发布时间】:2016-06-19 15:36:55
【问题描述】:
在 Bash 中创建这样的非线性管道的最简洁(最简单、最有效、最短、最快、最简单、最优雅)的方法是什么?
我有三个命令:mksock、irclogin 和 ircpingpong。我想将stdin、irclogin 和ircpingpong 导入mksock,并将mksock 导入stdout 和ircpingpong。这意味着mksock 和ircpingpong 在一个循环中。我画了一张图:
irclogin 只需要运行一次并成为mksock 的第一个输入。之后,ircpingpong 和 stdin 应该随时被接受。我目前正在使用这样的管道和临时文件:
#!/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
这工作,但我想知道是否有更好的方法来做到这一点。困扰我的是,我使用文件而不是管道从 ircpingpong 循环返回到 mksock 使用 tail。使用管道不起作用,因为据我了解,在tail -f 开始读取管道之前,已经向管道写入了一些内容,因此它错过了它。
让我感到困扰的是,我必须在脚本结尾处杀死 tail,因为它不会自行停止,即使在脚本结束后也会保持套接字连接。
【问题讨论】:
-
这就是 Coproceses 的用途。 Korn shell 和 bash 对它们的支持不同,bash 协进程是在 bash 4.0 中引入的。见wiki.bash-hackers.org/syntax/keywords/coproc
标签: bash shell unix pipelining