2009-04-01 2 views
0

Мне нужно запустить процесс, подождать несколько часов, убить его и запустить его снова. Есть ли простой способ, которым я могу выполнить это с помощью Python или Bash? Я могу запустить его в фоновом режиме, но как я могу определить, как использовать его?Как мне запланировать завершение процесса?

ответ

3

С Баш:

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

$! Баш переменная расширяется до PID самого недавно начатого фонового процесса. sleep просто ждет час, затем kill завершает этот процесс.

Цикл while просто продолжает делать это снова и снова.

+0

Неужели bash autoreap своих детей? Это либо оставит кучу зомби (если bash не будет autoreap), либо вы рискуете отправить SIGTERM в несвязанный процесс (bash autoreaps, освобождая pid для другого процесса). –

+0

Я предполагаю, что процесс не выходит (на основе вопроса), и в этом случае PID не будет повторно использоваться до его уничтожения. – paxdiablo

+0

Процесс действительно выходит, но он действительно длинный. Это решение отлично работает! – hekevintran

0

Одна идея: сохранить PID процесса (возвращенный fork() в дочернем процессе) в файл, либо либо запланировать задание cron, либо убить его вручную, читая PID из файла.

Другой вариант: создать оболочку сценария оболочки, которая автоматически убивает и перезапускает процесс. То же, что и выше, но вы можете хранить PID в памяти, спать столько, сколько вам нужно, убить процесс, а затем цикл.

0

Посмотрите на полезную утилиту start-stop-daemon.

+0

Ссылка сломана. –

+0

... Я установил его на тот, который работает, но вы должны проверить, что это нужная страница. –

+0

Да, это тот. Сожалею. – innaM

0

Вы всегда можете написать сценарий для поиска этих процессов и убить их, если они найдены. Затем добавьте cronjob для выполнения скрипта.

Find process ID of a process with known name

Kill processes with a known ID

В Python os.kill() может быть использован, чтобы убить процесс данный идентификатор.

3

Это в Perl, но вы должны иметь возможность перевести его на 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 
} 

Потому что я пытаюсь научить себя Python, здесь в Python (я не доверяю этот код):

#!/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) 
+0

Идентификатор процесса не может использоваться другим процессом, потому что ребенок еще не был извлечен родителем (это зомби). –

2

В 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() является Python> = 2.6.

На питона < = 2.5 вы можете использовать вместо этого:

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

Я получаю NameError: имя «подпроцесс» не определено –

+0

Добавление результатов подпроцесса импорта в AttributeError: объект «Popen» не имеет атрибута «kill» –

+0

@chas. owens: p.kill() для python> = 2.6. – nosklo

0

не идеальный метод, но если вы знаете название программы, и вы знаете, что это единственный способ это имя работает на вас системе может использовать это в хрон:

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

Это будет работать каждые два часа на час и убить ProgramName затем начать процесс снова.

Смежные вопросы