在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
此有效,但我想知道是否有更好的方法可以做到这一点。令我困扰的是,我使用文件而不是管道来使用tail从 ircpingpong 循环回 mksock 。使用管道并不起作用,因为根据我的理解,在尾部-f开始读取之前会有一些东西写入管道,因此它会错过它。令我感到困扰的是,我必须在脚本的末尾杀死尾巴,因为它不会停留在它自己的上面,并且即使在脚本结束后也会保持套接字连接。
答案 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
我们的想法是分别运行所有程序,并且只确保根据此图正确地重定向每个程序的输入和输出:
当然,ircpingpong
必须阅读stdin
并写信至stdout
,irclogin
必须写信至stdout
,mksock
必须从stdin
并写信给stdout
。
答案 1 :(得分:0)
这里只使用一个fifo。
fifo=/tmp/myfifo
rm $fifo
mkfifo $fifo
((ircpingpong < $fifo &) && irclogin && cat) | mksock | tee $fifo
根据需要添加stdbuf。
我不知道您是否会遇到“某些事情不会自行消亡”的问题;当我按ctrl键编辑脚本时,一切似乎都消失了。