计算从一个进程流到另一个进程的字节数


17

我正在运行一个Shell脚本,该脚本将数据从一个进程传输到另一个进程

process_a | process_b

有谁知道一种方法来找出两个程序之间传递了多少字节?我目前唯一能想到的解决方案是编写一个小的c程序,该程序从stdin读取,写入stdout并对所有传输的数据进行计数,并将计数存储在环境变量中,例如:

process_a | count_bytes | process_b

有人有更整洁的解决方案吗?

Answers:


16

通过dd管。dd的默认输入为stdin,默认输出为stdout;完成stdin / stdout I / O后,它将向stderr报告所传输的数据量。

如果要捕获dd的输出,并且其他程序已经与stderr通信,请使用另一个文件描述符。例如,

$ exec 4>~/fred
$ input-command | dd 2>&4 | output-command
$ exec 4>&-

2
您不能跳过exec并直接将其直接输出到文件吗?input-command | dd 2>~/fred | output-command
暂停,直到另行通知。

2
嗯是的 很抱歉,我显然处于“那些”时刻之一。
Phil P

28

使用pv管道查看器。这是一个很棒的工具。一旦知道了它,就永远不会知道没有它的生活。

它还可以显示进度条和传输的“速度”。


在搜索中,我遇到了这个问题,但是我需要它来设置一个变量,该变量具有传输的字节数,以便可以在其他进程中使用它。
西蒙·霍奇森

用法示例:cat file | pv -b将返回文件的大小。
rodorgas 18/09/27

6

process_a | tee >(process_b) | wc --bytes可能有用。然后,您可以将wc的计数重定向到您需要的任何位置。如果process_bstdout/ 输出任何内容,则stderr您可能需要将其重定向到某个地方(如果仅有)/dev/null

举一个人为的例子:

filestore:~# cat document.odt | tee >(dd of=/dev/null 2>/dev/null) | wc --bytes
4295

通过解释的方式:tee让您将输出定向到多个文件(加上stdout),并且>()构造是bash的“进程替换”,在这种情况下,该过程使进程看起来像只写文件,因此您可以重定向到进程以及文件(请参阅此处,或此问题+答案以获取用于tee将输出发送到许多流程的示例)。


我喜欢这种解决方案,可悲的是,我正在使用的Shelll(BusyBox)似乎不支持>()表示法,但它确实提供了一种我所追求的方式。
西蒙·霍奇森

是的,您需要一个相当完整的bash才能具有该功能-这是一种不常用的东西,因此会被剥离下来(甚至那些目标是与bash兼容的目标)像busybox一样以节省空间。
David Spillett

1

我知道我参加晚会很晚,但是我相信我有一个很好的答案,可以增强这个有用的线索。
这是@Phil P和@David Spillett答案的混合,但是:

  • 与@Phil P的不同之处在于,它避免创建新文件
  • 与@David Spillett的不同,它维护管道结构

字节数与process_b的任何输出一起输出到stdout。
在使用output(Bytes:在示例中)时,可以使用前缀来标识包含字节的行。

exec 3>&1
process_a | tee >({ echo -n 'Bytes:'; wc -c; } >&3) | process_b
exec 3>&-

警告:
请勿依赖输出中各行
的顺序该顺序是不可预测的,即使使用相同参数调用相同脚本时也可能总是不同!


可悲的是,它仍然只是一个仅适用于bash的结构……
Mikhail T.
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.