ProcFS in Linux has many useful information about process and its status. In this particular case I’ll show you how to determine progress while copying the file with cp. Same principle can be used for many other situations as well; like importing MySQL dump or whatever you comes up on your mind :-)

So in this situation I am copying the ~98GB file to another directory:

cp -a /input/archive.tar.gz /output/

First, let’s find PID of this process. As this is only cp process that I’m running on the system I can use:

root@ncc-1701 ~ # pidof cp
438

Otherwise I would use something like the following command and pick the correct one from the list:

ps auxw | grep cp

Now that we know PID of our process we can navigate to /proc/438/fd directory and look at file descriptors to determine which FD was assigned to the file we’re copying:

root@ncc-1701 /proc/438/fd # ls -alh
total 0
dr-x------ 2 root root  0 Apr 21 21:35 .
dr-xr-xr-x 9 root root  0 Apr 21 21:33 ..
lrwx------ 1 root root 64 Apr 21 21:35 0 -> /dev/pts/6
lrwx------ 1 root root 64 Apr 21 21:35 1 -> /dev/pts/6
lrwx------ 1 root root 64 Apr 21 21:35 2 -> /dev/pts/6
lr-x------ 1 root root 64 Apr 21 21:35 3 -> /input/archive.tar.gz
l-wx------ 1 root root 64 Apr 21 21:35 4 -> /output/archive.tar.gz

As we can see FD identified by number 3 is used as source while 4 is used as destination. To look at current progress we can cat fdinfo for that FD:

root@ncc-1701 /proc/438/fdinfo # cat 3
pos:    8260419584
flags:  0500000
mnt_id: 21

From that we can gather that cp is at 8260419584th byte of the file.

In order to calculate percentage of completion we need to divide position byte with size of the file and multiply it by 100. To determine file size simply use ls -l:

-rw-r--r-- 1 root root 104705417800 Jan 14 12:43 archive.tar.gz

Now that we have all the necessary information we can calculate percentage:

8780513280 / 104705417800
= 0,0838592067583

0,0838592067583 * 100
= 8,38592067583

With that we conclude that this cp process is currently at ~8%.