在一个命名管道(FIFO)的消费端,有没有办法将每个项目区分开来,并重定向到自己的进程?

问题描述 投票:0回答:1

我最好的解释是通过例子。

  1. 创建命名管道。mkfifo pipe
  2. 创建5个文本文件 a.txt, b.txt, c.txt, d.txt, e.txt (在本例中,它们可以容纳任何内容)
  3. cat [a-e].txt > pipe

当然,由于消费端管道没有打开,终端会显得很忙。

  1. 在另一个终端。tail -fn +1 pipe

所有的内容都通过管道送入(消耗并由尾巴打印出来),正如预期的那样。

但是,我不希望简单地打印出消耗的内容,而是希望每个管道中的文本文件被重定向到一个命令(5个独立的进程),一次只能处理一个。

比如说 python some-script.py < pipe 但它会创建5个不同的实例(每个文本文件内容一个实例)。

有没有办法让消费者区分进来的对象?还是说数据会被追加,并作为一个流来读取?

named-pipes fifo mkfifo
1个回答
0
投票

一个可能普遍适用的解决方案(期待听到是否有更有效的替代方案。

首先,问题所描述的一个python脚本例子。

some-script.py。

import sys

lines = sys.stdin.readlines()
print('>>>START-OF-STDIN<<<')
print(''.join(lines))
print('>>>END-OF-STDIN<<<')

我们的目标是让来自管道的文本流是可以区分的。

一个生产者的例子。

cat a.txt | echo $(base64 -w 0) | cat > pipe &
cat b.txt | echo $(base64 -w 0) | cat > pipe &
cat c.txt | echo $(base64 -w 0) | cat > pipe &
cat d.txt | echo $(base64 -w 0) | cat > pipe &
cat e.txt | echo $(base64 -w 0) | cat > pipe &

生产者的描述:

  • cat 连接整个文件,然后用管道输送到... echo
  • echo 显示来自子命令的文本 $(base64 -w 0) 和管子到 cat
  • base64 -w 0 将全部文件内容编码成一行
  • cat 在这种情况下使用的,是在将输出重定向到管道之前,将完整的行连接起来。如果没有它,消费者就不能正常工作(自己试试吧

消费者的一个例子。

tail -fn +1 pipe | while read line ; do (echo $line | base64 -d | cat | python some-script.py) ; done

对消费者的描述:

  • tail -fn +1 pipe 以下是对消费者的描述(-f)管从头开始(-n +1)而不退出进程,并将内容管道到 read 之内 while
  • 当有行要被读取的时候(假设base64编码的单行来自生产者),每一行都被传递到一个子shell中
  • 在每个子系统中
  • echo 管线到 base64 -d (-d代表解码)
  • base64 -d 将解码后的线路(现在可能跨越多条线路)输送到 cat
  • cat 连线,并将其作为一个管道输送到 python some-script.py
  • 最后,这个例子的python脚本能够以与 cat example.txt | python some-script.py

当一个主机进程没有Docker权限,但可以将一个FIFO(命名为管道)文件以卷的形式安装到容器中时,上述方法对我很有用。潜在的消费者的多个实例可以并行发生。我认为上面成功地将进来的内容区分开来,这样被隔离的过程可以处理从命名管道进来的内容。

涉及管道符号等的Docker命令的一个例子。

"bash -c 'tail -fn +1 pipe | while read line ; do (echo $line | base64 -d | cat | python some-script.py) ; done'"

© www.soinside.com 2019 - 2024. All rights reserved.