如何使在bash管道循环 [英] How to make a pipe loop in bash

查看:111
本文介绍了如何使在bash管道循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有程序 P0 P1 ... P(N -1)一些 N'GT; 0 。我怎么能轻易重定向程序的输出节目 P(i + 1的模N)所有 I 0℃= I< N )?

Assume that I have programs P0, P1, ...P(n-1) for some n > 0. How can I easily redirect the output of program Pi to program P(i+1 mod n) for all i (0 <= i < n)?

例如,假设我有一个程序平方,其中反复读取一个数字,比打印该数目的平方和程序,它有时打印出数字后,它希望能够读取它的平方。我如何连接这些程序,例如,每当打印数量,平方平方它返​​回到

For example, let's say I have a program square, which repeatedly reads a number and than prints the square of that number, and a program calc, which sometimes prints a number after which it expects to be able to read the square of it. How do I connect these programs such that whenever calc prints a number, square squares it returns it to calc?

编辑:也许我应该澄清我的意思为易。命名管道/ FIFO的解决方案是一个确实有效(我已经在过去使用),但它实际上需要相当多的工作,如果你使用一个bash管道比较它做正确。 (你需要获得一个尚未现有的文件名,使管道具有该名称,运行管循环,清理命名管道。)假设你再也不能写 PROG1 | PROG2 键,总是不得不使用命名管道连接方案。

I should probably clarify what I mean with "easily". The named pipe/fifo solution is one that indeed works (and I have used in the past), but it actually requires quite a bit of work to do properly if you compare it with using a bash pipe. (You need to get a not yet existing filename, make a pipe with that name, run the "pipe loop", clean up the named pipe.) Imagine you could no longer write prog1 | prog2 and would always have to use named pipes to connect programs.

我要找的东西,几乎是写一个正常的管一样简单。比如像 {PROG1 | PROG2}&GT;&安培; 0 将是巨大的。

I'm looking for something that is almost as easy as writing a "normal" pipe. For instance something like { prog1 | prog2 } >&0 would be great.

推荐答案

花很长一段时间昨天试图重定向后标准输出标准输入,我结束了下面的方法。这是不是真的很好,但我觉得我在命名管道/ FIFO的解决方案preFER它。

After spending quite some time yesterday trying to redirect stdout to stdin, I ended up with the following method. It isn't really nice, but I think I prefer it over the named pipe/fifo solution.

read | { P0 | ... | P(n-1); } >/dev/fd/0

{...}&GT;的/ dev / FD / 0 是标准输出重定向到标准输入管道序列作为一个整体(即它重定向输出P(N-1)至P0的输入)。使用&GT;&安培; 0 或类似的东西不能正常工作;这可能是因为bash的假设 0 是只读的,而它不介意写入的/ dev / FD / 0

The { ... } >/dev/fd/0 is to redirect stdout to stdin for the pipe sequence as a whole (i.e. it redirects the output of P(n-1) to the input of P0). Using >&0 or something similar does not work; this is probably because bash assumes 0 is read-only while it doesn't mind writing to /dev/fd/0.

的初始 -pipe是必要的,因为没有它的输入和输出文件描述符是相同的分设备(至少在我的系统)和重定向没有影响。 (该PTS设备不工作作为管;写它把你的屏幕上的东西)通过使 {...} 正常管道输入,重定向具有期望的效果。

The initial read-pipe is necessary because without it both the input and output file descriptor are the same pts device (at least on my system) and the redirect has no effect. (The pts device doesn't work as a pipe; writing to it puts things on your screen.) By making the input of the { ... } a normal pipe, the redirect has the desired effect.

要与我的 / 平方说明例如:

function calc() {
  # calculate sum of squares of numbers 0,..,10

  sum=0
  for ((i=0; i<10; i++)); do
    echo $i                   # "request" the square of i

    read ii                   # read the square of i
    echo "got $ii" >&2          # debug message

    let sum=$sum+$ii
  done

  echo "sum $sum" >&2           # output result to stderr
}

function square() {
  # square numbers

  read j                         # receive first "request"
  while [ "$j" != "" ]; do
    let jj=$j*$j
    echo "square($j) = $jj" >&2  # debug message

    echo $jj                     # send square

    read j                       # receive next "request"
  done
}

read | { calc | square; } >/dev/fd/0

运行上面的code给出了以下的输出:

Running the above code gives the following output:

square(0) = 0
got 0
square(1) = 1
got 1
square(2) = 4
got 4
square(3) = 9
got 9
square(4) = 16
got 16
square(5) = 25
got 25
square(6) = 36
got 36
square(7) = 49
got 49
square(8) = 64
got 64
square(9) = 81
got 81
sum 285

当然,这种方法是相当多的黑客攻击的。尤其是部分有不想要的副作用:真正的管道循环终止不会导致整个终止。我想不出什么好于,因为它似乎你只能确定由尝试写写东西给它的管道循环已经终止。

Of course, this method is quite a bit of a hack. Especially the read part has an undesired side-effect: termination of the "real" pipe loop does not lead to termination of the whole. I couldn't think of anything better than read as it seems that you can only determine that the pipe loop has terminated by try to writing write something to it.

这篇关于如何使在bash管道循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆