timed_run
timed_run.py
is a modified version of a Python script written by Chris Cooper that manages the
execution of external programs with the ability to terminate programs
which do not complete within a specified period of time.
timed_run.py can be used cross-platform to execute
programs. Under Linux and Mac OS X, all that is required is a Python
installation. On Windows, timed_run.py can be run in a
bash shell using cygwin along with the
cygwin installation of Python.
Like most such utilities, timed_run.py executes the
specified program in a child process and waits for the child process
to complete. If the child process has not terminated in the specified
time, timed_run.py will kill the child process and then
report on the exit status of the executed process by writing a simple
string to STDOUT.
In order for timed_run.py to be able to terminate the
program properly, the program must be executed in the initial child
process created by timed_run.py. This requirement has
consequences that must be handled when using timed_run.py
to execute Firefox and Thunderbird.
Using timed_run.py to execute a program
timed_run.py is called as follows:
timed_run.py timeout prefix program [argument1 [argument2 [...]]]
timeout specifies the time in seconds that timed_run will wait for the program to exit before killing it.
prefix is a string which is prepended to the EXIT STATUS output to help in locating the result of specific program calls.
program is the path to the program to be executed.
argument1, argument2, ... are the command line arguments to be passed to program.
timed_run.py will output a line describing the exit
status of the executed program.
prefix: EXIT STATUS: description (99.000000 seconds)
description will be one of:
NORMALif the program exited with exit code 0.ABNORMALif the program exited with exit code 1 or 2.CRASHED exitcodeif the program exited with an exit code greater than 2.CRASHED signal signalif the program exited due to a signal.TIMED OUTif the program did not terminate in the specified time and was killed bytimed_run.py.
Examples
Executing an invalid program path using timed_run.py
$timed_run.py 20 prefix nosuchprogram prefix: ERROR: nosuchprogram ['nosuchprogram'] failed: 2 (No such file or directory) (0.000000 seconds) prefix: EXIT STATUS: CRASHED 66 (0.017759 seconds)
Note how timed_run.py reports the operating system error and exit status
by outputting lines prefixed with the prefix argument.
Executing example.sh using timed_run.py
The following examples use the shell script example.sh. example.sh takes
two arguments which specify how long the script should take to complete and its exit code.
Normal program termination
$timed_run.py 20 prefix ./example.sh -e 0 -t 10 example.sh -e 0 -t 10 start Thu Mar 8 05:12:38 EST 2007 example.sh -e 0 -t 10 stop Thu Mar 8 05:12:48 EST 2007 prefix: EXIT STATUS: NORMAL (10.007722 seconds)
Abnormal program termination with exit code 1
$timed_run.py 20 prefix ./example.sh -e 1 -t 10 example.sh -e 1 -t 10 start Thu Mar 8 05:13:47 EST 2007 example.sh -e 1 -t 10 stop Thu Mar 8 05:13:57 EST 2007 prefix: EXIT STATUS: ABNORMAL 1 (10.007821 seconds)
Abnormal program termination with exit code 2
$timed_run.py 20 prefix ./example.sh -e 2 -t 10 example.sh -e 2 -t 10 start Thu Mar 8 05:14:01 EST 2007 example.sh -e 2 -t 10 stop Thu Mar 8 05:14:11 EST 2007 prefix: EXIT STATUS: ABNORMAL 2 (10.007566 seconds)
Abnormal program termination with exit code 3
$timed_run.py 20 prefix ./example.sh -e 3 -t 10 example.sh -e 3 -t 10 start Thu Mar 8 05:14:23 EST 2007 example.sh -e 3 -t 10 stop Thu Mar 8 05:14:33 EST 2007 prefix: EXIT STATUS: CRASHED 3 (10.008021 seconds)
Abnormal program termination due to time out
$timed_run.py 5 prefix ./example.sh -e 0 -t 10 example.sh -e 0 -t 10 start Thu Mar 8 05:14:54 EST 2007 prefix: EXIT STATUS: TIMED OUT (5 seconds)
Abnormal program termination due to signal
$timed_run.py 300 prefix ./example.sh -e 0 -t 300 example.sh -e 0 -t 300 start Thu Mar 8 05:16:48 EST 2007 prefix: EXIT STATUS: CRASHED signal 9 (12.902197 seconds)
Using timed_run.py to execute Firefox and Thunderbird.
Since the 1.8 branch, Firefox and Thunderbird normally restart due to
requests from the extension manager. This terminates the original process
which was executing the program and will cause timed_run.py
to think the program has terminated.
To work around this problem, you can tell the extension manager to not
restart by setting the environment variable
NO_EM_START. This will prevent timed_run.py
from terminating immediately, however it will not be able to kill the
running instance of Firefox on Linux or Mac OS X since the application
binary is executed in a different process than the original process
where the shell script which invoked Firefox or Thunderbird is run.
One approach which will allow timed_run.py to maintain
the ability to terminate Firefox and Thunderbird is to patch the
invokation scripts (firefox, thunderbird, run-mozilla.sh)
to exec the application binary. This will execute the
application binary in the same child process that
timed_run.py created.