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 monitor script. 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. The load lines are the system's default output from ^T; the lines with the filename are the output of the monitor command.

$ 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%
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
SIGUSR1 is the same progress monitoring interface as that offered by Linux's dd(1). It is a bit unwieldy compared to the FreeBSD interface, so I hope somebody will soon add SIGINFO support to the Linux kernel.

Comments   Toot! Share

Last modified: Monday, October 27, 2008 1:34 pm

Creative Commons Licence BY NC

Unless otherwise expressly stated, all original material on this page created by Diomidis Spinellis is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License.