Какой самый чистый способ создания нелинейного конвейера?

Какой самый чистый (самый простой, самый эффективный, самый короткий, самый быстрый, самый простой, самый элегантный) способ создать нелинейный конвейер, подобный этому, в Bash?

У меня есть три команды: mksock, irclogin и ircpingpong. Я хочу irclogin 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

Это работает, но я хочу знать, есть ли лучший способ сделать это. Меня беспокоит, что я использую файл, а не канал для возврата из ircpingpong в mksock с использованием tail. Использование канала не сработало, потому что, насколько я понимаю, что-то записывается в канал до того, как tail -f начинает читать с него, и поэтому он пропускает его.

Меня также беспокоит, что мне нужно убить tail в конце скрипта, потому что он не останавливается сам по себе и оставлял сокет подключенным даже после завершения скрипта.

Ответ 1

Я могу предложить версию без временных файлов и с двумя 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 и писать в stdout, irclogin должен писать в stdout, а mksock должен читать из stdin и писать в stdout.

Ответ 2

Здесь что-то, что использует только один fifo.

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

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

Добавьте stdbuf по мере необходимости.

Я не знаю, получишь ли ты свою проблему "что-то не умирает само по себе"; когда я ctrl-c'ed сценарий, все, казалось, умерло.