Question

I need to run a process, wait a few hours, kill it, and start it again. Is there an easy way that I can accomplish this with Python or Bash? I can run it in the background but how do I identify it to use kill on it?

Was it helpful?

Solution

With bash:

while true ; do
    run_proc &
    PID=$!
    sleep 3600
    kill $PID
    sleep 30
done

The $! bash variable expands to the PID of the most recently started background process. The sleep just waits an hour, then the kill shuts down that process.

The while loop just keeps doing it over and over.

OTHER TIPS

This is in Perl, but you should be able to translate it to Python.

#!/usr/bin/perl

use strict;
use warnings;

#set times to 0 for infinite times
my ($times, $wait, $program, @args) = @ARGV;

$times = -1 unless $times;
while ($times--) {
    $times = -1 if $times < 0; #catch -2 and turn it back into -1
    die "could not fork" unless defined(my $pid = fork);

    #replace child with the program we want to launch
    unless ($pid) {
        exec $program, @args;
    }

    #parent waits and kills the child if it isn't done yet
    sleep $wait;

    kill $pid;
    waitpid $pid, 0; #clean up child
}

Because I am trying to teach myself Python, here it is in Python (I do not trust this code):

#!/usr/bin/python

import os
import sys
import time

times    = int(sys.argv[1])
wait     = int(sys.argv[2])
program  = sys.argv[3]
args     = []
if len(sys.argv) >= 4:
    args = sys.argv[3:]

if times == 0:
    times = -1

while times:
    times = times - 1
    if times < 0:
        times = -1

    pid = os.fork()

    if not pid:
        os.execvp(program, args)

    time.sleep(wait)

    os.kill(pid, 15)
    os.waitpid(pid, 0)

In python:

import subprocess
import time

while True:    
    p = subprocess.Popen(['/path/to/program', 'param1', 'param2'])
    time.sleep(2 * 60 * 60) # wait time in seconds - 2 hours
    p.kill()

p.kill() is python >= 2.6.

On python <= 2.5 you can use this instead:

os.kill(p.pid, signal.SIGTERM)

You could always write a script to search for those processes and kill them if found. Then add a cronjob to execute the script.

Find process ID of a process with known name

Kill processes with a known ID

In python os.kill() can be used to kill a process given the id.

Take a look at the start-stop-daemon utility.

One idea: Save the process's PID (returned by fork() in your child process) to a file, then either schedule a cron job to kill it or kill it manually, reading the PID from the file.

Another option: Create a shell script wrapper that automatically kills and restarts the process. Same as above, but you can keep the PID in memory, sleep for as long as you need, kill the process, then loop.

Not an ideal method but if you know the name of the program and you know it's the only process of that name running on the system you can use this in cron:

0 */2 * * * kill `ps -ax | grep programName | grep -v grep | awk '{ print $1 }'` && ./scriptToStartProcess

This will run every two hours on the hour and kill programName then start the process again.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top