2011-01-16 12 views
67

Hallo、Linuxサービス/デーモンとしてのPythonスクリプト

私はpythonスクリプトを(ubuntu)Linux上でサービス(デーモン)として実行しようとしています。

は、ウェブ上のようないくつかのソリューションが存在する:

http://pypi.python.org/pypi/python-daemon/

A行儀のUnixデーモンプロセスが権利を取得するのが難しいですが、必要な手順は非常にすべてのデーモンプログラムで同じです。 DaemonContextインスタンスは、プログラムの動作と構成されたプロセス環境を保持します。コンテキストマネージャーとしてインスタンスを使用してデーモン状態を入力します。

import signal 
import time 
import multiprocessing 

stop_event = multiprocessing.Event() 

def stop(signum, frame): 
    stop_event.set() 

signal.signal(signal.SIGTERM, stop) 

if __name__ == '__main__': 
    while not stop_event.is_set(): 
     time.sleep(3) 
:しかし、私はUbuntuは私の解決策は、init.dスクリプト

#!/bin/bash 

WORK_DIR="/var/lib/foo" 
DAEMON="/usr/bin/python" 
ARGS="/opt/foo/linux_service.py" 
PIDFILE="/var/run/foo.pid" 
USER="foo" 

case "$1" in 
    start) 
    echo "Starting server" 
    mkdir -p "$WORK_DIR" 
    /sbin/start-stop-daemon --start --pidfile $PIDFILE \ 
     --user $USER --group $USER \ 
     -b --make-pidfile \ 
     --chuid $USER \ 
     --exec $DAEMON $ARGS 
    ;; 
    stop) 
    echo "Stopping server" 
    /sbin/start-stop-daemon --stop --pidfile $PIDFILE --verbose 
    ;; 
    *) 
    echo "Usage: /etc/init.d/$USER {start|stop}" 
    exit 1 
    ;; 
esac 

exit 0 

とPythonでとの組み合わせであるLinuxに特異的に私のPythonスクリプトを統合したいと

http://www.jejik.com/articles/2007/02/a_simple_unix_linux_daemon_in_python/

私の質問は、このアプローチが正しい場合です。追加の信号を処理する必要がありますか?それは "正常に動作するUnixデーモンプロセス"ですか?

答えて

84

あなたのデーモンが何らかの方法で連続して実行されていると仮定すると(何らかのイベントループ、ねじれなど)、upstartを試すことができます。ここで

は、仮想的なPythonのサービスのための一例成り上がり設定です:

description "My service" 
author "Some Dude <[email protected]>" 

start on runlevel [234] 
stop on runlevel [0156] 

chdir /some/dir 
exec /some/dir/script.py 
respawn 

あなたは、単純な/etc/initにscript.confとしてこれを保存する場合は

$ sudo initctl reload-configuration 
$ sudo start script 

一回の操作を行いますが、それを停止することができますstop scriptとなります。上のスタートアップのconfの言うことは、再起動時にこのサービスを開始し、サービスが終了した場合に再起動することです。

シグナル処理に関しては、プロセスは当然SIGTERMに応答するはずです。デフォルトでは、独自のシグナルハンドラを特別にインストールしていない限り、これを処理する必要があります。

+2

あなたは右、成り上がりは、今日の標準であります!上記のスクリプトはSIGTERMを処理するので、あなたの設定ファイルでOKになるはずです:) – tauran

+0

スクリプトを起動するように変更しました。それは正常に動作します。 – tauran

+10

今作った1つの追加調整。あなたのpythonスクリプトがvirtualenvの下で実行されている場合は、環境から実行可能なPython実行ファイルを使用するためにupstartを変更するだけです: 'exec /home/user/.env/environ/bin/python/some/dir/script.py' –

8

リョトンの答えが良いです。ここでは、私はデバッグの時間を過ごしたので、光の洗練があります。そして私は適切にフォーマットできるように新しい答えを出す必要があります。

デバッグに永遠に連れて行ってくれたカップルの他のポイント:あなたは

  1. を、それが失敗した場合、
  2. /var/log/upstart/.log最初のチェックをスクリプトがとデーモンを実装している場合、 'expect daemon'スタンザを使用しないでください。 「期待」の作品はありません。どうしてか分かりません。 (理由を知っていれば投稿してください!)
  3. また、 "initctl status script"をチェックして、起動(起動/実行)していることを確認してください。ここで

を(あなたがあなたのconfファイルを更新するとき、リロードを行う)私のバージョンです:

description "My service" 
author "Some Dude <[email protected]>" 

env PYTHON_HOME=/<pathtovirtualenv> 
env PATH=$PYTHON_HOME:$PATH 

start on runlevel [2345] 
stop on runlevel [016] 

chdir <directory> 

# NO expect stanza if your script uses python-daemon 
exec $PYTHON_HOME/bin/python script.py 

# Only turn on respawn after you've debugged getting it to start and stop properly 
respawn 
+0

この設定をコピーすると/ etc/initに入力し、service myservicenameと入力してください。どうしたの。 – David

+0

'service myservice start'の後に' initctl reload-configuration'を実行しましたか? –

+0

申し訳ありませんが、現在は動作しています。サービスサービス名を入力していましたが、私のオプションを明らかにしていないと思っていました。サービス名の開始停止または再起動が必要です。とにかくお返事ありがとう – David

関連する問題