Solution 1:

You can use rsync to do the copy. If you use the -P option (show progress), it does just that.

I tend to use rsync -avP <source> <dest> for most copying.

Solution 2:

You can pipe things into the pv command to add progress indication to programs that might not have their own progress meter.

cp -a source/ dest/ | pv

However if I'm doing a copy large enough that I need a progress bar I end up using rsync anyway as Jeremy recommends. He also points out that you'll need to arrange your pipeline so that the data is piped though pv - the example gives only tells you how much data the cp is printing out, not how much is being copied. Something like this will work for single files: pv source > dest.

However, for copying directories, you'll need to get more complex.