以前、Debianで自作スクリプトをデーモンにして使っている事を書いた。
前書いた記事はこちら
でも、そろそろArchLinuxでも自分で作ったスクリプトをデーモンにしたいので、調べてみたら
思いの外簡単で結構あっけなかった。
Debianというかinit.dで使っていたスクリプト自体は何もソースをいじらなかった。
サンプルのスクリプト
ただ一秒ごとにインクリメントした数字をテキストに書くという簡単なスクリプト(in Python)
#!/usr/bin/python
import os
import sys
import time
def createDaemon():
pid = os.fork()
if pid > 0:
f2 = open('/var/run/oredaemon.pid','w')
f2.write(str(pid)+"\n")
f2.close()
sys.exit()
if pid == 0:
i = 0
while True:
f = open('/home/oreusr/testest.txt','a')
f.write(str(i) + "\n")
f.close()
time.sleep(1)
i += 1
if __name__ == '__main__':
createDaemon()
/home/oreusr/testest.txtの部分は架空のPathだけれども
各々の環境に合わせて好きな様に入れてね。
スクリプトの説明をすると、forkというシステムコールを読んで
プロセスを2つに分ける。
(分身みたいになる。fork()以降はパラレルワールドみたいに別のプロセスで同時に2つのプログラムが実行される)
親プロセスの場合はfork()の戻り値は子プロセスのPIDが返ってくるので、
PIDをメモするPIDファイルに書き込んだあと、
自身は終了する。
子プロセスの場合はそのまま無限ループに入る。
親プロセスが終了した子プロセスは、すべての根源であるinitプロセスに養子に出される。
養子プロセスはそのままバックグラウンドで動作することになる。
これがデーモンの仕組み。
Systemdでデーモンを設定する
さっきのPythonのスクリプトはこのまま実行すると、
何も起きないままコマンドは終了した様に思える。
ただpsコマンドなどで見てみると、スクリプトは動いていることは確認できる。
終了するにはkillコマンドで終了させることができる。
この実行や終了をsystemdで管理しよう。
デーモン名は何でも良いのだけれども、
orenodaemonってことにしよう。
orenodaemonデーモンを作るには、
/usr/lib/systemd/system/orenodaemon.service
というファイルを作る。
中身はこんな
[Unit]
Description=My Test Nanimoshinai Daemon
[Service]
ExecStart=/usr/local/share/PyDaemon.py
Restart=always
Type=forking
PIDFile=/var/run/oredaemon.pid
[Install]
WantedBy=multi-user.target
Descriptionは単なる説明
ExecStartは先ほど作ったスクリプトの場所
Typeはforking
PIDFileはスクリプトの中身を見てみるとわかるけれども、pidを出力しているテキストファイルの場所を示している。
あとはコピペで構わない。
このファイルを作ったあとは以下のコマンドでデーモンを再読み込みをする。
sudo systemctl daemon-reload
この今しがた作ったファイルの名orenodaemon.serviceがsystemdのサービス名、つまりデーモン名だ。
serviceの場合は.serviceを省略しても構わない。
sudo systemctl start orenodaemon
このコマンドを実行すればtestest.txtファイルにどんどん数字が書き込まれているのが確認できると思う。
起動時にデーモンを動かしたかったら
sudo systemctl enable orenodaemon
おまけ
しかし、markdownのエディタ入れたけれど
シンタックスハイライトがうまく行かん…