Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I was wandering if there is a Linux program that can limit data throughput of a pipe - in actual bytes per second?.

From what I gather, applicable for the purposes would be

What I'd want is to be able to specify something like

cat example.txt | ratelimit -Bps 100 > /dev/ttyUSB0

... and actually have a single byte from example.txt sent each 1/100 = 0.01 sec (or 10 ms) to 'output'..

share|improve this question

migrated from stackoverflow.com Mar 20 '11 at 8:03

This question came from our site for professional and enthusiast programmers.

You could try mbuffer (don't know if it is in Debian by default):

cat example.txt | mbuffer -R 100 > /dev/ttyUSB0
share|improve this answer
    
Hi @bmk, thanks and +1 for your answer, as I didn't know about mbuffer: measuring buffer! Also, sudo apt-get install mbuffer is OK in Ubuntu.. However, -R 100 raises 'mbuffer: fatal: invalid low value for option "-R" - missing suffix?'; at least 101 is needed (as per mbuffer.c). Finally, it seems it uses the limit just to fill its own intermediate buffer - but still writes in chunks with large Bps (while it buffers, I have no activity on USB!) Thanks & cheers! – sdaau Mar 18 '11 at 10:37

pv can also do it. Here are some moderately contrived examples:

  • pv --rate-limit 1 /dev/zero > /dev/null
  • pv --quiet --rate-limit 16 /dev/urandom | hd
  • pv --quiet --rate-limit 10485760 /dev/zero | gzip | hd
  • head -c 1000 < /dev/zero | pv --size 1000 --rate-limit 150 | sha1sum
share|improve this answer
up vote 0 down vote accepted

Well, I decided to patch cpipe, you can find the patch here: cpipe-3.0.1-singlebyte.patch; it's in respect to current 'apt-get source cpipe' in Lucid (which gets me cpipe_3.0.1.orig.tar.gz and cpipe_3.0.1-1.diff.gz); when the source downloads and unpacks the cpipe-3.0.1 dir, simply do:

$ cp -a cpipe-3.0.1 cpipe-3.0.1B
$ cd cpipe-3.0.1B
$ patch -p1 < /path/to/cpipe-3.0.1-singlebyte.patch
$ make

Added a command line switch -bs for 'byte single' which can now support single byte writes down to 1 Bps; so now can do:

$ echo "hello" | ./cpipe -vt -vw -bs 1 | cat 
./cpipe: period 1 sec, 1000.000000 ms, 1000000000 ns, 0.000000 nsrem 
h out: 1000.122ms at       0B/s (      6B/s avg)       6B
e out: 2000.343ms at       0B/s (      2B/s avg)       6B
l out: 3000.536ms at       1B/s (      1B/s avg)       6B
l out: 4000.730ms at       1B/s (      1B/s avg)       6B
o out: 5000.925ms at       1B/s (      0B/s avg)       6B

 out: 6001.100ms at       1B/s (      0B/s avg)       6B
 out: 6001.155ms at       1B/s (      0B/s avg)       6B
thru: 6001.209ms at       1B/s (      1B/s avg)       6B

$ echo "hello" | ./cpipe -vt -vw -bs 5 > /dev/null
./cpipe: period 0 sec, 200.000000 ms, 200000000 ns, 200000000.000000 nsrem 
 out: 200.120ms at       0B/s (     30B/s avg)       6B
 out: 400.323ms at       2B/s (     10B/s avg)       6B
 out: 600.507ms at       3B/s (      5B/s avg)       6B
 out: 800.690ms at       4B/s (      3B/s avg)       6B
 out: 1000.870ms at       4B/s (      2B/s avg)       6B
 out: 1201.049ms at       4B/s (      1B/s avg)       6B
 out: 1201.098ms at       5B/s (      1B/s avg)       6B
thru: 1201.142ms at       5B/s (      5B/s avg)       6B

... however, this won't work all too well for higher kB/s rates - so in that case, it's better to use the usual cpipe -s buffered technique ...

$ cat /etc/X11/rgb.txt | ./cpipe -vt -vw -bs 102400 > /dev/null
....
 out: 2675.206ms at    6.3kB/s (      1B/s avg)   17.0kB
 out: 2675.240ms at    6.3kB/s (      1B/s avg)   17.0kB
thru: 2675.832ms at    6.3kB/s (   6.3kB/s avg)   17.0kB

$ cat /etc/X11/rgb.txt | ./cpipe -vt -vw -s 100 > /dev/null
 out:   0.011ms at    1.5GB/s (   1.5GB/s avg)   17.0kB
thru: 166.630ms at  101.9kB/s ( 101.9kB/s avg)   17.0kB

..., as it says also in man cpipe:

Since on most systems there is a certain minimum time usleep() sleeps, e.g. 0.01s, it is impossible to reach high limits with a small buffer size

Well.. hope to hear there's a better way of controlling this,
Cheers!

share|improve this answer

Here is also a Perl-only script, cratelimit.pl - possibly not very accurate, but seems to do the trick somewhat (-r argument accepts bytes per second):

cat whatever | ./cratelimit.pl -r=50000
share|improve this answer

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .