contenttaichino.com永遠のネバーランドDaemonContextでpythonスクリプトをデーモン化するpythonでデーモンを書きたいと思って、調べてみると「Pythonでprefork型のデーモンを書く」という記事を見つけました。この内容が素晴しくて、プロセスもデーモンも初心者な僕でも処理の大枠を理解できました。それで、デーモン化する為のモジュールってあるんじゃないのと思いpypiを見てみると、複数のモジュールが登録されていました。その中で一番リッチな機能を持つDaemonContextを使ってみる事にしました。インストールはeasy_installで一発です。python-daemon使い方も簡単でDaemonContextオブジェクトを作成して、そのwith構文中がDaemon化されます。僕が便利だと感じているのは、pidファイルの指定と標準入出力先のリダイレクトです。これらの機能はDaemonContextのコンストラクタにパラメータを指定することで使用できます。先ほどのサンプルで上記の2機能を使うと以下のようになります。do_some_task()これでデーモンのpidが記述されたファイルが/tmp/mydaemon.piに作成されます。/tmp/mydaemon.pid`と書く事が出来ますね。標準エラー出力をfake_err_console.txtに設定しています。スクリプトをデーモン化すると、プロセスがターミナルからデタッチされるのでデバッグがしにくいのですが、これで最低限のデバッグは出来るようになります。他にも機能が1通りそろっているので、ソースのクラス定義を1度眺めてみても良いと思います。問題が1つあって、マルチプロセスなデーモンを作ろうとすると、先日のエントリの話と同じで、DaemonContextがatexitメソッドを使ってpidファイルの削除処理を実装しているため、子プロセスの終了時にpidファイルが削除されてしまい、肝心の親プロセスをkillする際にはpidファイルが残ってません。いうわけでマルチプロセスなデーモンを使う際はpidファイルの処理は自前で実装する必要がありますが、それ以外のデーモン化ならこのモジュールは非常に便利ですね。7:10:55本文で指摘されている問題とは直接関係ありませんが、DatemonContext()にuidを引き渡した場合、rootでスクリプトを起動、setuid(uid)した後でpidfile.__enter__が実行される設計にも問題があります。PIDLockFileだと指定されたディレクトリがそのユーザで読み書きできないとエラーになります。root所有の/var/runを使いたくても使えません。