Linux 从管道中读取数据并写入标准输出,中间有一个延迟。也必须处理二进制文件

Linux 从管道中读取数据并写入标准输出,中间有一个延迟。也必须处理二进制文件,linux,bash,Linux,Bash,我已经试了大约一个小时来寻找这个问题的优雅解决方案。我的目标基本上是编写一个带宽控制管道命令,我可以在各种情况下重用它(不仅仅是用于网络传输,我知道scp-l 1234)。我想做的是: 延迟X秒 从管道读取Yamount(如果没有足够的数据,则小于Y) 将读取的数据写入标准输出 其中: X可以是1..n Y可以是1字节,最大值为某个高值 我的问题是: 它必须支持Bash无法很好处理的二进制数据 我走过或至少想到过的道路: 在读取数据时使用构造,它会过滤使用的编码中的所有白色字符 使用d

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

  • 延迟
    X
  • 从管道读取
    Y
    amount(如果没有足够的数据,则小于Y)
  • 将读取的数据写入标准输出
  • 其中:

    • X
      可以是
      1..n
    • Y
      可以是1字节,最大值为某个高值
    我的问题是:

    • 它必须支持Bash无法很好处理的二进制数据
    我走过或至少想到过的道路:

    • 在读取数据时使用
      构造,它会过滤使用的编码中的所有白色字符
    • 使用
      dd bs=1 count=1
      和循环
      dd
      if
      和not中有内容时,似乎没有不同的退出代码。这使得知道何时停止循环变得更加困难。如果我将标准错误重定向到一个临时文件,读取它以检查是否传输了某些内容(就像在stderr上打印的统计数据中一样),然后重复,那么这个方法应该可以工作。但我怀疑,如果在大量数据上使用它,速度会非常慢,如果可能的话,我想跳过创建任何临时文件

    关于如何使用Bash尽可能干净地解决这个问题,您有什么想法或建议吗?

    您必须在Bash中完成吗?您是否可以只使用现有的程序,例如


    cstream满足带宽控制管道命令的目标,但不一定满足与特定算法或实现语言相关的其他标准。

    使用
    head-c如何

    cat /dev/zero | head -c 10 > test.out
    

    给你一个10字节的文件

    它不太优雅,但您可以使用一些重定向技巧捕获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。

    可能是pv-qL速率

       -L RATE, --rate-limit RATE
              Limit the transfer to a maximum of RATE  bytes  per  second.   A
              suffix of "k", "m", "g", or "t" can be added to denote kilobytes
              (*1024), megabytes, and so on.
    

    是的。但我的目标是从管道中多次读取
    ,并在每次读取
    之间设置延迟<代码>读取
    无法指示管道是否为空,因此读取回路可能会被制动。所以我不能使用
    阅读
    。但是谢谢你的建议!在Bash中实现它也有一些好处(可移植性&不需要单独安装应用程序)。但是
    cstream
    看起来对我非常有用。好建议!看起来很有趣。
    &4
    4>&1
    做什么?今晚我将试用你的代码。我还要看一下
    pv
    ,目标是限制带宽,同时学习新的东西;然后和dd。。。2>&1 >&4 | ... dd的标准错误(其中打印传输的字节数)重定向到管道,本地标准输出重定向到文件描述符4;我建议你读一下:@karatedog stackoverflow不是个人顾问。每个人都能从答案中受益,即使没有立即得到答案。上面的答案实际上解决了我的一些问题。自从我写了那篇评论,在那2.5年里,我变得更加聪明了。