13

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

我有三个命令:mksockircloginircpingpong。我想通过管道将stdin,ircloginircpingpong输入mksock, 并通过管道mksock输入stdoutand ircpingpong。这意味着mksockandircpingpong处于一个循环中。我画了一张图:

图表

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

行得通,但我想知道是否有更好的方法来做到这一点。困扰我的是,我使用的是文件而不是管道来使用 tail从ircpingpong循环回到mksock 。使用管道不起作用,因为据我了解,在tail -f开始读取管道之前已将某些内容写入管道,因此它错过了它。

我必须在脚本末尾杀死 tail 也让我感到困扰,因为它不会自行停止,即使在脚本结束后也会保持套接字连接。

4

2 回答 2

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和写入stdoutirclogin必须写入stdout,并且mksock必须读取stdin和写入stdout

于 2016-03-16T14:03:12.670 回答
0

这是只使用一个fifo的东西。

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

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

根据需要添加 stdbuf。

我不知道您是否会遇到“事物不会自行消亡”的问题;当我 ctrl-c'ed 脚本时,一切似乎都死了。

于 2018-10-19T22:11:08.060 回答