There are already some really great answers here, but here are my favorite commands, including my own little spin on the rsync command, with my favorite options:
watch 'du -hs' (or, for more granularity: watch -n 1 'du -sk | awk '\''{printf "%.3f MiB %s\n", $1/1024, $2}'\''') allows you to watch a destination folder grow in size if cp is already runningWhat if you already started a long cp process and don't want to stop it now?
Assuming you already started this copy command:
# recursively copy source_dir_name to destination
cp -r source_dir_name destination
Just open up a new terminal, with the copy operation already in progress, and run:
# cd into destination directory
cd path/to/destination/source_dir_name
# Now watch, live, the size of this destination grow!
watch 'du -hs'
# OR (Preferred!) see even more granularity, in X.xxx MiB:
watch 'du -sk | awk '\''{printf "%.3f MiB %s\n", $1/1024, $2}'\'''
This will cause the watch command to automatically run du -hs (or du -sk | awk '{printf "%.3f MiB %s\n", $1/1024, $2}') every 2 seconds (the default for watch) inside your destination directory, so you can see the size of the folder grow in real-time! This doesn't give you a percentage complete, but if you have a rough idea of the size of what you're copying, it certainly gives you something to watch and feel good about, knowing the destination is growing. Here's a sample output on the watch screen:
Cmd: watch 'du -hs'
Output:
Every 2.0s: du -hs 2.5G .
Cmd: watch 'du -sk | awk '\''{printf "%.3f MiB %s\n", $1/1024, $2}'\'''
Output:
Every 2.0s: du -sk | awk '{printf "%.3f MiB %s\n", $1/1024, $2}' 2560.348 MiB .
Above, you can see the current size of the current directory (.) is 2.5 GiB, or, more specifically in the 2nd case: 2560.348 MiB. To make watch use a slower update interval, such as 5 seconds, just add -n 5 to the watch command, like this:
watch -n 5 'du -hs'
# OR (preferred, for more granularity)
watch -n 5 'du -sk | awk '\''{printf "%.3f MiB %s\n", $1/1024, $2}'\'''
rsync really is best for thisMy favorite commands:
# dry-run
time rsync -rah --dry-run --info=progress2 --stats source destination
# real copy (Important! Do a dry run first and read the
# output summary to ensure you're copying what you intend!)
time rsync -rah --info=progress2 --stats source destination
Note: the time part at the front of the above commands just outputs a nice time summary of the total run-time for the operation in the end. This works before any Linux command.
Here's what an rsync --stats summary for a --dry-run looks like, by the way:
$ rsync -rah --dry-run --info=progress2 --stats /media/gabriel/cdrom ~/temp 2.76G 100% 2570.10GB/s 0:00:00 (xfr#3836, to-chk=0/4837) Number of files: 4,837 (reg: 3,836, dir: 1,001) Number of created files: 0 Number of deleted files: 0 Number of regular files transferred: 3,836 Total file size: 2.76G bytes Total transferred file size: 2.76G bytes Literal data: 0 bytes Matched data: 0 bytes File list size: 0 File list generation time: 0.001 seconds File list transfer time: 0.000 seconds Total bytes sent: 123.88K Total bytes received: 15.54K sent 123.88K bytes received 15.54K bytes 278.85K bytes/sec total size is 2.76G speedup is 19,792.78 (DRY RUN)
watch -n 5 'du -sk | awk '\''{printf "%.3f MiB %s\n", $1/1024, $2}'\''' type command, in my ROS tutorial: my ROS.org tutorial: Reading messages from a bag filersync usage and stuff: Super User: Convert NTFS partition to ext4 - How to copy the data?