Run job for a period of time

I have a job that runs for an unspecified amount of time. I want to run this as a cron job for a specified amount of time, say 2 hours. Once the time is up, the program should be killed in the middle of execution. How can I do this?

Thanks.

If your process is written in C and you have access to the code, you can use the alarm(2) function which will generate a SIGALARM signal after a specified number of seconds. You can capture the signal for a graceful exit or let it abort the program.

You can do the same with a script by sending a HUP signal to your script via at(1). At the beginning of your script, run the following command:

echo "/bin/kill -HUP $$" | at now + 120 minutes

With a trap, the HUP signal could be intercepted for a graceful termination or, as in the alarm(2) example, let it abort the script. Also, the at-job number could be saved used to remove it from the queue if your script completes early.

A third option would be to create a pid-file from within your process (giving it a shell wrapper if necessary). Then you could cron another job to check for the existence of the pid file after a specified period of time and send a signal to it if the PID is still active.

Here's kind of a not-too-useful example:

#!/bin/ksh

    trap 'echo terminated counts: $I : $J : $K ; exit 3' HUP

    echo "kill -HUP $$" | at now + 1 minute

    I=0

    while [ $I -lt 1000 ]
    do
        J=0

        while [ $J -lt 1000 ]
        do
            K=0

            while [ $K -lt $J ]
            do
                (( K = K + 1 ))
            done

            (( J = J + 1 ))
        done

        (( I = I + 1 ))
    done

     echo final counts $I : $J : $K
    exit 0

Wow, that's just what I needed. I appreciate you going through with the effort with this.
I have some questions though:

  • why do I get the following message each time when I run the above script in succession:
    Job 2 will be executed using /bin/sh
    Job 3 will be executed using /bin/sh
    ...

  • in general, is there a preference of using SIGHUP over SIGINT in these situations?

this is one more way of implementing;

./yourscript.ksh & sleep 7200; kill $!

run your script as a background process; then sleep for specified number of seconds later send a signal to the process put in background using the last background identifier from ksh builtin variables

That's cool, too. Thanks!

By default, the at command uses the Bourne shell. What you're seeing with "Job 2 will be executed using /bin/sh" message is a warning. You can call at with a -k option to tell it to use the Korn shell.

As far as SIGHUP vs SIGINT, it depends on the process you're trying to interrupt. Many processes handle SIGHUPs gracefully -- for example syslogd will reread its configuration file. Other process, if not coded specifically for processing SIGHUP will terminate. SIGINTs, on the other hand, are almost universally "process-terminating". Experiment.

I'm glad I could be of help.