2010-06-01 25 views
5

Tôi có một chương trình dựa trên Python hoạt động mà tôi muốn chạy như một daemon. Hiện tại tôi đang thực hiện theo cách rất bắt đầu với phiên bản screen-d -m name và giết nó với pkill -9 -f name.Làm cách nào để quản lý một daemon dựa trên Python trên Linux?

Cuối cùng, tôi phải chuyển sang hệ thống tốt hơn chúng tôi sử dụng ở đây (do đó Tôi không sẵn sàng sửa đổi chương trình) nhưng tạm thời, tôi đang tìm cách làm sạch hơn điều này.

Suy nghĩ hiện tại của tôi là khởi động nó như một tác vụ nền từ tập lệnh inti.d nhưng làm cách nào để viết phần đó để đưa nó trở lại?

Trả lời

1

Bắt đầu nó với một phong cách kịch bản init.d là một cách tốt. Bạn mang nó xuống với tín hiệu POSIX ... Xem StackOverflow, Signal handling in Python.

+0

Tôi có thể 'giết -9' cho tất cả những gì tôi quan tâm, nhưng tôi không biết cách tìm ra PID của nó một cách đáng tin cậy như thế nào. – BCS

+0

@BCS: '-9' thường là ... * quá mức cần thiết * (tha thứ cho trò chơi chữ). Xem [kill -9] (http://speculation.org/garrick/kill-9.html). Đối với việc tìm PID của nó, script của bạn có thể tạo một pidfile trong '/ var/run' hoặc sử dụng một lib cho phép bạn đặt' argv [0] 'thành một số tên được xác định dễ sử dụng với' pkill'. –

6

Trên linux, có một tiện ích start-stop-daemon như một phần của công cụ init.d.

Rất linh hoạt và cho phép các cách khác nhau để chụp pid máy chủ của bạn.

Ngoài ra còn có một tệp /etc/init.d/sk mà có thể dùng làm cơ sở cho tập lệnh init.d của riêng bạn.

Nếu nền tảng mục tiêu của bạn dựa trên debian, bạn nên tạo gói debina để triển khai vì nó cũng giúp tích hợp đúng daemon trong phần còn lại của hệ thống. Và nó không phải là quá phức tạp (nếu bạn đã làm nó mười lần trước ;-)

+0

Trông giống như những thứ tốt. – BCS

3

Nếu bạn muốn làm điều đó với mã trong python, đây là một phương pháp C khá chuẩn được chuyển đến python mà tôi sử dụng. Nó hoạt động hoàn hảo và thậm chí bạn có thể chọn đầu ra tệp.

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) 

Sau đó, bạn có thể sử dụng tín hiệu để phát hiện khi tín hiệu giết được gửi đến chương trình và thoát độc đáo. Ví dụ từ 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 
+0

phương pháp ngã ba kép hoạt động giống như một sự quyến rũ! – pygabriel

0

Hãy thử question trở lên chính xác chấp nhận giải pháp này.

+0

Tôi thực sự không thích muck với nội bộ của chương trình. Tôi muốn giữ những gì tôi đang sử dụng hơn là làm điều đó. – BCS

+0

Thực sự bạn không cần phải thay đổi chương trình của mình, nếu nó có thể nhập được. Joust nhập khẩu chính của bạn trong deamon-ví dụ Chạy phương pháp, (thay thế trong khi vòng lặp). – Ib33X

2

Có các mô-đun có thể được sử dụng để sao chép tập lệnh python.

python-daemon triển khai đặc tả daemon được xử lý tốt (PEP 3143).

Ngoài ra this module gần đây đã xuất hiện trên github có vẻ có nhiều chất pythonic và dễ sử dụng hơn.

Các vấn đề liên quan