Подтвердить что ты не робот

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

Какой самый чистый (самый простой, самый эффективный, самый короткий, самый быстрый, самый простой, самый элегантный) способ создать нелинейный конвейер, подобный этому, в 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 в конце скрипта, потому что он не останавливается сам по себе и оставлял сокет подключенным даже после завершения скрипта.

4b9b3361

Ответ 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 сценарий, все, казалось, умерло.