在Bash中创建非线性管道的最简洁方法是什么?

时间:2016-03-05 22:44:03

标签: bash shell unix linear pipelining

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

我有三个命令: mksock irclogin ircpingpong 。我想将 stdin irclogin ircpingpong 连接到 mksock ,并管道 mksock 进入 stdout ircpingpong 。这意味着 mksock ircpingpong 处于循环中。我画了一张图。 Diagram

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

有效,但我想知道是否有更好的方法可以做到这一点。令我困扰的是,我使用文件而不是管道来使用tail从 ircpingpong 循环回 mksock 。使用管道并不起作用,因为根据我的理解,在尾部-f开始读取之前会有一些东西写入管道,因此它会错过它。令我感到困扰的是,我必须在脚本的末尾杀死尾巴,因为它不会停留在它自己的上面,并且即使在脚本结束后也会保持套接字连接。

2 个答案:

答案 0 :(得分:4)

我可以建议一个没有临时文件的版本,以及两个fifo-s:

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

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

我们的想法是分别运行所有程序,并且只确保根据此图正确地重定向每个程序的输入和输出:

pipe-flow

当然,ircpingpong必须阅读stdin并写信至stdoutirclogin必须写信至stdoutmksock必须从stdin并写信给stdout

答案 1 :(得分:0)

这里只使用一个fifo。

fifo=/tmp/myfifo
rm $fifo
mkfifo $fifo

((ircpingpong < $fifo &) && irclogin && cat) | mksock | tee $fifo

根据需要添加stdbuf。

我不知道您是否会遇到“某些事情不会自行消亡”的问题;当我按ctrl键编辑脚本时,一切似乎都消失了。

相关问题