Проверьте, запущен ли скрипт Python - PullRequest
85 голосов
/ 25 апреля 2009

У меня есть демон python, работающий как часть моего веб-приложения / Как я могу быстро проверить (используя python), работает ли мой демон и, если нет, запустить его?

Я хочу сделать это таким образом, чтобы исправить любые сбои демона, и поэтому скрипт не нужно запускать вручную, он автоматически запустится, как только он будет вызван, а затем продолжит работу.

Как я могу проверить (используя python), работает ли мой скрипт?

Ответы [ 19 ]

1 голос
/ 04 сентября 2014

Вместо того, чтобы разрабатывать свое собственное файловое решение PID (в котором больше тонкостей и угловых случаев, чем вы могли бы подумать), взгляните на supervisord - это система управления процессом, которая облегчает упаковку управление заданиями и поведение демона вокруг существующего скрипта Python.

0 голосов
/ 27 апреля 2017

Простой пример, если вы ищете только имя процесса, существует или нет:

import os

def pname_exists(inp):
    os.system('ps -ef > /tmp/psef')
    lines=open('/tmp/psef', 'r').read().split('\n')
    res=[i for i in lines if inp in i]
    return True if res else False

Result:
In [21]: pname_exists('syslog')
Out[21]: True

In [22]: pname_exists('syslog_')
Out[22]: False
0 голосов
/ 22 сентября 2016

Вот более полезный код (с проверкой, выполняет ли скрипт именно python):

#! /usr/bin/env python

import os
from sys import exit


def checkPidRunning(pid):
    global script_name
    if pid<1:
        print "Incorrect pid number!"
        exit()
    try:
        os.kill(pid, 0)
    except OSError:
        print "Abnormal termination of previous process."
        return False
    else:
        ps_command = "ps -o command= %s | grep -Eq 'python .*/%s'" % (pid,script_name)
        process_exist = os.system(ps_command)
        if process_exist == 0:
            return True
        else:
            print "Process with pid %s is not a Python process. Continue..." % pid
            return False


if __name__ == '__main__':
    script_name = os.path.basename(__file__)
    pid = str(os.getpid())
    pidfile = os.path.join("/", "tmp/", script_name+".pid")
    if os.path.isfile(pidfile):
        print "Warning! Pid file %s existing. Checking for process..." % pidfile
        r_pid = int(file(pidfile,'r').readlines()[0])
        if checkPidRunning(r_pid):
            print "Python process with pid = %s is already running. Exit!" % r_pid
            exit()
        else:
            file(pidfile, 'w').write(pid)
    else:
        file(pidfile, 'w').write(pid)

# main programm
....
....

os.unlink(pidfile)

Вот строка:

ps_command = "ps -o command= %s | grep -Eq 'python .*/%s'" % (pid,script_name)

возвращает 0, если "grep" успешен, и процесс "python" в настоящее время выполняется с именем вашего скрипта в качестве параметра.

0 голосов
/ 08 августа 2016

попробуйте это:

#/usr/bin/env python
import os, sys, atexit

try:
    # Set PID file
    def set_pid_file():
        pid = str(os.getpid())
        f = open('myCode.pid', 'w')
        f.write(pid)
        f.close()

    def goodby():
        pid = str('myCode.pid')
        os.remove(pid)

    atexit.register(goodby)
    set_pid_file()
    # Place your code here

except KeyboardInterrupt:
    sys.exit(0)
0 голосов
/ 28 февраля 2014
ps ax | grep processName

если сценарий отладки в pycharm всегда завершается,

pydevd.py --multiproc --client 127.0.0.1 --port 33882 --file processName
0 голосов
/ 12 июня 2012

Другие ответы отлично подходят для таких вещей, как задания cron, но если вы работаете с демоном, вы должны следить за ним с помощью чего-то вроде daemontools .

0 голосов
/ 12 июля 2012

Рассмотрим следующий пример для решения вашей проблемы:

#!/usr/bin/python
# -*- coding: latin-1 -*-

import os, sys, time, signal

def termination_handler (signum,frame):
    global running
    global pidfile
    print 'You have requested to terminate the application...'
    sys.stdout.flush()
    running = 0
    os.unlink(pidfile)

running = 1
signal.signal(signal.SIGINT,termination_handler)

pid = str(os.getpid())
pidfile = '/tmp/'+os.path.basename(__file__).split('.')[0]+'.pid'

if os.path.isfile(pidfile):
    print "%s already exists, exiting" % pidfile
    sys.exit()
else:
    file(pidfile, 'w').write(pid)

# Do some actual work here

while running:
  time.sleep(10)

Я предлагаю этот скрипт, потому что он может быть выполнен только один раз.

0 голосов
/ 21 июня 2018

Это то, что я использую в Linux, чтобы не запускать скрипт, если он уже запущен:

import os
import sys


script_name = os.path.basename(__file__)
pidfile = os.path.join("/tmp", os.path.splitext(script_name)[0]) + ".pid"


def create_pidfile():
    if os.path.exists(pidfile):
        with open(pidfile, "r") as _file:
            last_pid = int(_file.read())

        # Checking if process is still running
        last_process_cmdline = "/proc/%d/cmdline" % last_pid
        if os.path.exists(last_process_cmdline):
            with open(last_process_cmdline, "r") as _file:
                cmdline = _file.read()
            if script_name in cmdline:
                raise Exception("Script already running...")

    with open(pidfile, "w") as _file:
        pid = str(os.getpid())
        _file.write(pid)


def main():
    """Your application logic goes here"""


if __name__ == "__main__":
    create_pidfile()
    main()

Этот подход хорошо работает без какой-либо зависимости от внешнего модуля.

0 голосов
/ 15 июня 2013

Использование bash для поиска процесса с именем текущего скрипта. Нет дополнительного файла.

import commands
import os
import time
import sys

def stop_if_already_running():
    script_name = os.path.basename(__file__)
    l = commands.getstatusoutput("ps aux | grep -e '%s' | grep -v grep | awk '{print $2}'| awk '{print $2}'" % script_name)
    if l[1]:
        sys.exit(0);

Чтобы проверить, добавьте

stop_if_already_running()
print "running normally"
while True:
    time.sleep(3)
...