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

kxe2p93d  于 2023-06-22  发布在  Unix
关注(0)|答案(6)|浏览(183)

给定一个形式的bash命令行

commandA | commandB

我想在commandAcommandB之间添加一个大小约为1MB的缓冲区。我希望能用这种形式的东西来做这件事

commandA | BUFFER | commandB

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

daolsyd0

daolsyd01#

BUFFER称为buffer。(man 1缓冲区,可能在apt-get安装缓冲区之后)

vmpqdwk3

vmpqdwk32#

还有另一个工具,pv- pipe viewer:

process1 | pv -pterbTCB 1G | process2
  • B指定缓冲区大小,此处为1千兆字节
  • C禁用splice,这是B所必需的
  • T显示缓冲区级别
  • pterb是由于存在T而需要的默认显示开关

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

kdfy810k

kdfy810k3#

你可以用

  • 缓冲液(已提及)
  • mbuffer(也适用于solaris,可能适用于其他UNIX)

例如

process1 | mbuffer -m 1024M | process2

使用1G缓冲区

cotxawn7

cotxawn74#

程序buffer使用共享内存。这可能是一个问题,因为在错误的情况下,内存可能会泄漏,因为共享内存可能比分配内存的程序更长。
另一种方法可以是GNU dd

commandA |
dd status=none iflag=fullblock bs=1M |
commandB

使用fullblock选项很重要。否则,dd在从管道阅读时可能会导致数据丢失。

dd参数说明

  • 状态=无

设置要打印的信息的级别为stderr;“none”抑制 debugging 误消息外的所有内容

  • iflag=全块

累积完整的输入块

  • bs=1M

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

zzwlnbp8

zzwlnbp85#

有一个名为stdbuf的工具,可以让您指定管道的缓冲区大小,类似于:

stdbuf -o 1M commandA | commandB
tjvv9vkg

tjvv9vkg6#

或者,你可以使用一个命名管道并并行运行它们:

mkfifo myfifo
commandB < myfifo &
commandA > myfifo
rm myfifo

相关问题