【问题标题】:What is the cleanest way to create a non-linear pipeline?创建非线性管道的最简洁方法是什么?
【发布时间】:2016-06-19 15:36:55
【问题描述】:

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

我有三个命令:mksockircloginircpingpong。我想将stdinircloginircpingpong 导入mksock,并将mksock 导入stdoutircpingpong。这意味着mksockircpingpong 在一个循环中。我画了一张图:

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

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

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

【问题讨论】:

标签: bash shell unix pipelining


【解决方案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

想法是分开运行所有程序,只保证每个程序的输入和输出按照这个图正确重定向:

当然,ircpingpong 必须读取stdin 并写入stdoutirclogin 必须写入stdout,而mksock 必须读取stdin 并写入stdout

【讨论】:

    【解决方案2】:

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

    fifo=/tmp/myfifo
    rm $fifo
    mkfifo $fifo
    
    ((ircpingpong < $fifo &) && irclogin && cat) | mksock | tee $fifo
    

    根据需要添加标准缓冲区。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-02-07
      • 1970-01-01
      • 1970-01-01
      • 2017-02-09
      • 2011-04-10
      • 1970-01-01
      相关资源
      最近更新 更多