我已经尝试了大约一个小时来找到这个问题的优雅解决方案。我的目标基本上是编写一个带宽控制管道命令,我可以在各种情况下重用它(不仅仅是网络传输,我知道 scp -l 1234)。我想做的是:

  • 延迟 X 秒。
  • 从管道中读取 Y 数量(如果不够,则小于 Y)数据。
  • 将读取的数据写入标准输出。

  • 在哪里:
  • X 可以是 1..n
  • Y 可以是 1 字节到某个高值。

  • 我的问题是:
  • 必须支持 Bash 不能很好处理的二进制数据。

  • 我走过或至少想到的道路:
  • 使用 while read data 构造,它过滤您使用的编码中的所有白色字符。
  • 使用 dd bs=1 count=1 和循环。 dd 似乎没有不同的退出代码,因为 if 中存在某些内容而不是某些内容。这使得更难知道何时停止循环。如果我将标准错误重定向到临时文件,则此方法应该有效,读取它以检查是否传输了某些内容(如 stderr 上打印的统计信息中所示)并重复。但是我怀疑如果在大量数据上使用它会非常慢,如果可能的话我想跳过创建任何临时文件。

  • 关于如何使用 Bash 尽可能干净地解决这个问题的任何想法或建议?

    最佳答案

    它不是很优雅,但您可以使用一些重定向技巧来捕获 dd 复制的字节数,然后将其用作 while 循环的退出条件:

    while [ -z "$byte_copied" ] || [ "$byte_copied" -ne 0 ]; do
        sleep $X;
        byte_copied=$(dd bs=$Y count=1 2>&1 >&4 | awk '$2 == "byte"{print $1}');
    done 4>&1
    

    但是,如果您的意图是限制传输吞吐量,我建议您使用 pv。

    关于linux - 从管道读取数据并写入标准输出,中间有延迟。也必须处理二进制文件,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/1463113/

    10-11 03:25
    查看更多