繁体   English   中英

如何使两个程序使用std io通信?

[英]How to have two programs communicate using std io?

我有两个不同的程序A和B。这两个程序都将用户输入从stdin输入到stdout。 我如何让程序互相对话? 即我希望程序A使用B作为标准输出和标准输入,程序B将A的输出作为标准输入并将其自己的输出提供给A。

我似乎无法弄清楚如何使用Linux管道做到这一点。

我正在使用bash。 我想要一个不涉及创建另一个程序或修改任何现有程序的解决方案。

socat使您可以将I / O从任何东西中继到其他任何东西,包括两个程序之间:

$ cat a
#!/bin/bash -e
var="World"
echo "$var"
echo "a wrote '$var'" >&2
read -r var
echo "a read '$var'" >&2

$ cat b
#!/bin/bash -e
read -r var
echo "b read '$var'" >&2
echo "Hello $var"
echo "b replied" >&2

$ chmod +x a b

$ socat exec:./a exec:./b
b read 'World'
b replied
a wrote 'World'
a read 'Hello World'

请注意,您有责任通过确保两个程序都适当地刷新其缓冲区来避免死锁。

如果将exec:./b替换为exec:rev ,则会导致死锁,因为大多数标准工具默认都会将输出缓冲到管道中。

我希望程序A使用B作为标准输出和标准输入,程序B将A的输出作为标准输入并将其自己的输出提供给A。

创建两个fifos并运行A | B A | B在后台,但将输入从fifo连接到A,将输出从b连接到fifo。 然后将fifos与cat连接在一起:

fifoAin=$(mktemp -u)
fifoBout=$(mktemp -u)
mkfifo "$fifoAin" "$fifoBout"
A < "$fifoAin" | B > "$fifoBout" &
cat < "$fifoBout" > "$fifoAin"

以下内容虽然看起来很酷,但却无法使用(!),因为cat将阻止文件描述符:

exec 3<> <(A | B)
cat <&3 >&3

带有注释的示例:

# output 1
# then read number and if a number is greater then 20
# output the number on stderr and exit
# otherwise add to number 3 and output
A() {
  echo 1
  while read n; do
    if ((n > 20)); then
      echo "Answer: $n" >&2
      break;
    fi
    echo "$((n + 3))"
  done
}


# read a number and output the number multiplied by 2
B() {
  while read n; do
    echo "$((n * 2))"
  done
}

# the code
fifoAin=$(mktemp -u)
fifoBout=$(mktemp -u)
mkfifo "$fifoAin" "$fifoBout"
A < "$fifoAin" | B > "$fifoBout" &
cat < "$fifoBout" > "$fifoAin"

将在stderr上输出:

Answer: 26

可能值得考虑您需要实现的目标以及实现此目标的最佳方法。

您当前的软件有问题。 即使使用bash ,也很难正确地实现解决方案(伪代码)(A || B)&&(B || A)。 可能会有更简单,更清洁的解决方案。 例如删除A和B之间的依赖关系,或修改软件以使A依赖B,反之亦然。

例如,如果B仅依赖于A的输出,则所需要做的就是用管道将A和B连接起来,以及从A到B的数据流:

A || B

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM