Bash 在两个命令之间的管道中添加一个大缓冲区

Bash 在两个命令之间的管道中添加一个大缓冲区,bash,unix,Bash,Unix,给定表单的bash命令行 commandA | commandB commandA | BUFFER | commandB 我想在commandA和commandB之间添加一个大小约为1MB的缓冲区。 我希望能用这种形式的东西做到这一点 commandA | commandB commandA | BUFFER | commandB 但是用于缓冲区的命令是什么 备注:我这样做是为了将这两个命令解耦,使它们更好地并行化。问题在于commandB以大数据块处理数据,这目前意味着command

给定表单的bash命令行

commandA | commandB
commandA | BUFFER | commandB
我想在
commandA
commandB
之间添加一个大小约为1MB的缓冲区。 我希望能用这种形式的东西做到这一点

commandA | commandB
commandA | BUFFER | commandB
但是用于
缓冲区的命令是什么

备注:我这样做是为了将这两个命令解耦,使它们更好地并行化。问题在于
commandB
以大数据块处理数据,这目前意味着
commandA
会一直阻塞,直到
commandB
使用数据块完成为止。所以一切都是按顺序运行的:-(

缓冲区称为缓冲区。(man 1缓冲区,可能在apt获得安装缓冲区之后)

您可以使用

  • 缓冲区(已提及)
  • mbuffer(也适用于solaris,可能适用于其他Unix)
例如


要使用1G缓冲区,您也可以使用命名管道并并行运行它们:

mkfifo myfifo
commandB < myfifo &
commandA > myfifo
rm myfifo
mkfifo myfifo
命令bmyfifo
rm myfifo
还有另一个工具-管道查看器:

process1 | pv -pterbTCB 1G | process2
  • B
    指定缓冲区大小,此处为1千兆字节
  • C
    禁用
    拼接
    ,这是
    B
  • T
    显示缓冲区级别
  • pterb
    是由于存在
    T

pv
可能在
mbuffer/buffer
不在官方存储库中的系统上可用(例如
arch-linux
).

程序
缓冲区使用共享内存。这可能是一个问题,因为在发生错误时,内存可能会泄漏,因为共享内存可能比分配内存的程序寿命长

另一种选择可能是GNU
dd

commandA |
dd status=none iflag=fullblock bs=1M |
commandB
使用
fullblock
选项非常重要。否则从管道读取数据时,
dd
可能会导致数据丢失

已解释的
dd
参数

  • 状态=无

    设置要打印到stderr的信息级别;“无”将抑制除错误消息以外的所有信息

  • iflag=全块

    累积完整的输入块

  • bs=1M

    一次最多读取和写入1兆字节(默认值:512字节)


要获得缓冲区大小,应该传递给缓冲区的选项是什么,例如1Gb缓冲区大小?似乎有很多选项可以配置块大小、块数量等等,但我不清楚要使用哪些选项来获得给定大小的简单缓冲区。
-m size
是总数。如果需要更细粒度的控制,请使用
-s blocksize-b块
放在一起。这只缓冲了大约64KB的空间——不大。这个解决方案的缓冲区大小与
commandA | commandB
相同。mbuffer似乎比buffer好得多,因为buffer是(根据manpage和我的实验)限制为1GB。我尝试使用
pv
作为缓冲区,但当缓冲区未满时,当其输出阻塞时,它有时会停止读取输入。这似乎是一个错误,因为附加
strace
可以修复它。
pv
带有缓冲区也会每隔100毫秒在读取和写入之间切换,或者直到没有更多数据准备好,但这是错误当我尝试时,从磁盘读取的速度变慢了。我想100毫秒的间隔太长了,系统无法继续向前读取。