Как мне управлять демоном на основе Python в Linux?

У меня есть работающая программа на основе Python, которую я хочу запустить как демон. В настоящее время я делаю это очень хакерским способом, начиная с сеанса screen-d -m name и убить его с помощью pkill -9 -f name.

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

В настоящее время я думаю, что запускаю его как фоновую задачу из сценария inti.d, но как мне написать часть, чтобы вернуть его обратно?


person BCS    schedule 01.06.2010    source источник


Ответы (6)


См. PEP 3143 -- Стандартная библиотека процессов демона

person vartec    schedule 01.06.2010

В Linux есть утилита start-stop-daemon как часть файла init. д инструменты.

Он очень гибкий и позволяет разными способами захватить pid вашего сервера.

Существует также файл /etc/init.d/skeleton, который может служить основой для вашего собственного сценария init.d.

Если ваша целевая платформа основана на Debian, имеет смысл создать пакет debina для ее развертывания, так как это также помогает правильно интегрировать демон в остальную систему. И это не так уж сложно (если вы уже делали это десять раз ;-)

person Peter Tillemans    schedule 01.06.2010

Если вы хотите сделать это с помощью кода на Python, это довольно стандартный метод C, который был портирован на Python, который я использую. Он работает безупречно, и вы даже можете выбрать вывод файла.

import os
import signal
def daemonize(workingdir='.', umask=0,outfile='/dev/null'):
#Put in background
pid = os.fork()
if pid == 0:
    #First child
    os.setsid()
    pid = os.fork() #fork again
    if pid == 0:
        os.chdir(workingdir)
        os.umask(umask)
    else:
        os._exit(0)
else:
    os._exit(0)

#Close all open resources
try:
    os.close(0)
    os.close(1)
    os.close(2)
except:
    raise Exception("Unable to close standard output. Try running with 'nodaemon'")
    os._exit(1)

#Redirect output
os.open(outfile, os.O_RDWR | os.O_CREAT)
os.dup2(0,1)
os.dup2(0,2)

Затем вы можете использовать сигналы, чтобы поймать, когда программе был отправлен сигнал уничтожения, и выйти красиво. Пример из Python Docs

import signal, os

def handler(signum, frame):
    print 'Signal handler called with signal', signum
    raise IOError("Couldn't open device!")

# Set the signal handler and a 5-second alarm
signal.signal(signal.SIGALRM, handler)
signal.alarm(5)

# This open() may hang indefinitely
fd = os.open('/dev/ttyS0', os.O_RDWR)

signal.alarm(0)          # Disable the alarm
person Chris    schedule 01.06.2010

Существуют модули, которые можно использовать для демонизации скрипта Python.

python-daemon реализует спецификацию демона с хорошим поведением (PEP 3143).

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

person Sergey R    schedule 06.12.2011

Начать его со сценария в стиле init.d — хороший способ. Вы снимаете это с помощью сигналов POSIX... См. StackOverflow, Обработка сигналов в Python.

person Aiden Bell    schedule 01.06.2010
comment
Я могу kill -9 его, мне все равно, но я не знаю, как надежно найти его PID. - person BCS; 01.06.2010
comment
@BCS: -9 часто ... излишнее (простите за каламбур). См. kill-9. Что касается нахождения его PID, ваш скрипт может создать pid-файл в /var/run или использовать библиотеку, которая позволяет вам установить argv[0] какое-либо легко идентифицируемое имя для использования с pkill. - person Dennis Williamson; 01.06.2010

Попробуйте этот вопрос или более точно принятое решение.

person Ib33X    schedule 01.06.2010
comment
Я действительно предпочел бы не возиться с внутренностями программы. Черт возьми, я лучше оставлю то, что использую сейчас, чем буду делать это. - person BCS; 01.06.2010
comment
На самом деле вам не нужно менять вашу программу, если она импортируема. Joust импортирует ваш основной метод запуска в демоне-примере (замените цикл while). - person Ib33X; 02.06.2010