2010-11-18 2 views
8

Мне нужно создать скрипт, который получает от пользователя следующее:процесс уничтожения с помощью python

1) Имя процесса (на linux).

2) Имя файла журнала, в котором этот процесс записывается.

Необходимо уничтожить процесс и убедиться, что процесс не работает. Измените имя файла журнала на новое имя файла с указанием времени и даты. И затем снова запустите процесс, убедитесь, что он работает, чтобы он продолжал записывать в файл журнала.

Заранее благодарим за помощь.

+0

имен процессов не являются уникальными на Linux. Что делать, если есть несколько процессов с тем же именем? Кроме того, как система знает, как перезапустить процесс? Кажется, вы дублируете функциональность logrotate. – Spacedman

+0

Как вы можете быть уверены, что убитый процесс на самом деле записывается в этот файл журнала? Звучит опасно предположить, что пользователь не ошибся. Являются ли эти ошибки созданием критических нежелательных ситуаций? – Danosaure

+0

Хотя это верно в отношении подпроцесса, для действительно простых команд, где пользователю не нужна какая-либо дополнительная сложность подпроцессов с использованием os.system, на самом деле проще и кодировать, и понимать. Для моей работы я без проблем использовал os.system. –

ответ

17

Вы можете получить идентификатор процесса (PID) дал это имя с помощью pgrep команду:

import subprocess 
import signal 
import os 
from datetime import datetime as dt 


process_name = sys.argv[1] 
log_file_name = sys.argv[2] 


proc = subprocess.Popen(["pgrep", process_name], stdout=subprocess.PIPE) 

# Kill process. 
for pid in proc.stdout: 
    os.kill(int(pid), signal.SIGTERM) 
    # Check if the process that we killed is alive. 
    try: 
     os.kill(int(pid), 0) 
     raise Exception("""wasn't able to kill the process 
          HINT:use signal.SIGKILL or signal.SIGABORT""") 
    except OSError as ex: 
     continue 

# Save old logging file and create a new one. 
os.system("cp {0} '{0}-dup-{1}'".format(log_file_name, dt.now())) 

# Empty the logging file. 
with open(log_file_name, "w") as f: 
    pass 

# Run the process again. 
os.sytsem("<command to run the process>") 
# you can use os.exec* if you want to replace this process with the new one which i think is much better in this case. 

# the os.system() or os.exec* call will failed if something go wrong like this you can check if the process is runninh again. 

Надеется, что это может помочь

2

Если вы знаете, как сделать это в терминале, то вы можете использовать следующие:

import os 
os.system("your_command_here; second_command; third; etc") 

Так что вы в конечном итоге своего рода мини-скрипт внутри питона. Я также хотел бы рассмотреть возможность создания этого сценария оболочки самостоятельно, а затем вызвать его из python:

import os 
os.system("path/to/my_script.sh") 

Приветствия!

+0

Мне нравится простота, и есть одна вещь, чтобы добавить «os.system» возвращает код состояния выхода, чтобы вы могли проверить успех процесса и обработать ошибки по коду. – snarkyname77

+0

Как правило, программистам больше не рекомендуется использовать os.system, так как subprocess.Popen предоставляет множество дополнительных опций и поддержки. В частности, он гораздо лучше справляется с аргументами командной строки и позволяет выводить конвейер. –

+0

Спасибо Джеймс, я переключусь на подпроцесс :) – Morlock