From FreeBSDwiki
Jump to: navigation, search

pv is acronymic for Pipe Viewer, and can be found in the ports tree at /usr/ports/sysutils/pv.

This is a very handy console-based tool which gives you a progress bar for any sort of data stream. For example, if you are using dd to clone one drive to another, you'd probably like to have a progress bar available - being able to kill -INFO the dd process is better than nothing, but it's far from ideal. pv to the rescue:

# dd if=/dev/ad0 bs=16M | pv | dd bs=16M of=/dev/ad1 
832MB 0:00:30 [  31MB/s] [                            <=>                    ]

Of course, 832MB is probably not really a little over half of the drive - in this example, pv can't really tell you when the process will be done, as it doesn't know how large the stream of data to be moved really is. But it does show you how long you've been running, how much data you've moved, how fast it's been moving, and the progress bar will bounce back and forth so at least you see movement. A more elegant example in this case would be to pass pv the actual expected size of the data directly:

# dd if=/dev/ad0 bs=16M | pv -s 512M | dd bs=16M of=/dev/ad1 
224MB 0:00:08 [31.7MB/s] [==============>                    ] 43% ETA 0:00:10

Much more satisfying! Now we get a percentage, a solid progess bar, and an ETA. Note that pv understands standard size delineations of K, M, and G; so no need to memorize powers of 2 to ridiculous levels. It's also worth noting that you can pass a stream with multiple stages through multiple pv instances - for example, what if instead of cloning one drive to another, we were sending its cloned image through gzip to make a compressed image file on a filesystem somewhere?

Just to make it easy to simulate this kind of thing, in this example what we'll actually do is compress a bunch of zeros from /dev/zero and pass them through gzip and into a file. Note that while we use the -s 2G switch in the first pv instance, we don't in the second - because the second will actually be measuring gzip's output, which we don't know the size of ahead of time... but it's nice to see it while the file is actually being written! Also note that we use the -N switch to name each of the progress bars, and the -c switch to put a line break between them.

# dd if=/dev/zero bs=10M count=1024 | pv -s 2G -N dd | gzip - | pv -cN gzip > /home/jrs/zero.bin.gz
    gzip: 1.05MB 0:00:17 [63.8kB/s] [            <=>                         ]       
     dd: 1.06GB 0:00:17 [64.3MB/s] [===========>            ] 52% ETA 0:00:15

Not bad - now we have progress bars showing us how much of our data we have left to get through, how long it will take us, how big our compressed image has gotten so far, and what basic rate it's growing at.

Personal tools