Monitor Process Progress on Unix
I often run file-processing commands that take many hours to finish, and I therefore need a way to monitor their progress. The Perkin-Elmer/Concurrent OS32 system I worked-on for a couple of years back in 1993 (don't ask) had a facility that displayed for any executing command the percentage of work that was completed. When I first saw this facility working on the programs I maintained, I couldn't believe my eyes, because I was sure that those rusty Cobol programs didn't contain any functionality to monitor their progress.
With a little more digging I discovered that the facility was part of the operating system's batch command monitor. Because batch commands typically process input files to create some output, the system calculated a job's progress simply by monitoring the percentage of the input file(s) read. I decided I wanted to implement such a facility under Unix, and after evaluating various design options (kernel modification, a command attaching to a process) I settled for a shell script. I wrote a FreeBSD-specific script in 2006, and yesterday I also ported it to Linux by taking advantage of the /proc/[0-9]*/fdinfo file that got introduced in the 2.6.22 kernel. Although the scripts depend on a couple of system-specific features, their small size and use of widely-available programs mean that they can be (relatively) easilly ported to various Unix systems offering similar features.
From the following links you can download
the Linux version and
the FreeBSD version of the
Simply put the script in your path and give it execute permission.
To use the monitor script
you specify the command you wish to run as an
argument to the script.
Then, under FreeBSD,
by pressing the SIGINFO key (^T; a FreeBSD extension) you
get a list of files that the command is currently reading and
the percentage of each file that has been read.
Here is an example of monitoring the progress of egrep
searching for four-letter palindromes in the system's dictionary.
load lines are the system's default output from
^T; the lines with the filename are the output of the monitor
$ monitor egrep '(.)(.)(.)(.)\4\3\2\1' /usr/share/dict/words load: 0.12 cmd: egrep 28951 [runnable] 1.75u 0.00s 7% 1056k /usr/share/dict/web2 17.09% load: 0.19 cmd: egrep 28951 [runnable] 2.70u 0.01s 9% 1056k /usr/share/dict/web2 24.97% load: 0.19 cmd: egrep 28951 [runnable] 4.36u 0.01s 15% 1056k /usr/share/dict/web2 40.75% overappareled load: 0.19 cmd: egrep 28951 [runnable] 6.42u 0.01s 25% 1064k /usr/share/dict/web2 59.15% load: 0.26 cmd: egrep 28951 [runnable] 8.60u 0.01s 32% 1064k /usr/share/dict/web2 78.86%Under Linux, you get the progress display by sending SIGUSR1 to the monitor process.
killall -USR1 monitor