Imshoo

独学で勉強しているプログラミングのメモ

systemdで定期実行

systemdで自作プログラムを定期実行させる際のメモ

OS:Linux Mint 19

なかなかできずに手間取ったのでうまくいった方法をかいておく。
まずは定期実行させるプログラムを適当に用意する。

func main() {
    flag.Parse()
    f, err := os.OpenFile(filepath, os.O_RDWR|os.O_CREATE|os.O_APPEND, 777)
    if err != nil {
        panic(err)
    }
    defer f.Close()
    fmt.Fprintln(f, hello+flag.Arg(0))
}

コマンドで受け取った文字列をhelloと結合してファイルに出力するだけのプログラム。
このプログラムがこのように配置されているとする。

root/
  └ program/
     ├ test.txt
     ├ main.go
     └ main // buildして生成されたファイル

systemdで定期実行させるファイルとして直接mainを指定すると動かなかったので、シェルスクリプトでmainファイルを実行する処理を書き同じディレクトリに配置する。このとき一度実行ファイルのあるディレクトリに移動してからファイルを実行させる。

#!/bin/sh

cd /root/program
./main world
root/
  └ program/
     ├ test.sh
     ├ test.txt
     ├ main.go
     └ main // buildして生成されたファイル

次に○○○.serviceファイルと○○○.timerファイルを作成し/etc/systemd/systemに配置する。
○○○.serviceは実行したい処理に関する記述をするファイルで○○○.timerは指定したserviceを定期実行させるファイルということになると思う。
今回はgotest.serviceとgotest.timerというファイル名にする。

まずはsrviceファイルのExecStart部分に実行したいファイルへの絶対パスをいれる。さきほど説明した通り直接mainファイルを指定すると動かなかったのでtest.shを指定。

// gotest.service
[Unit]
Description=test service

[Service]
Type=simple
ExecStart=/root/program/test.sh

[Install]
WantedBy=multi-user.target

そしてtimerファイルのUnit部分に定期実行させたいservice名を入れる。
定期実行する時間や間隔はOnCalender部分などに記述するが書き方がいろいろあるよう。調べたらでてくる。
今回は1分ごとに実行するようにminutelyと書く。

// gotest.timer
[Unit]
Description=test timer

[Timer]
OnCalendar=minutely
Unit=gotest.service

[Install]
WantedBy=timers.target

この2つのファイルを/etc/systemd/systemに配置してコマンドを打つと定期実行するようになる

// service起動
systemctl start [servie ファイル名]

// serviceをとめるときはこれ
systemctl stop [servie ファイル名]

動作していなかった場合はタイマーが登録されているか確認したりserviceのログを見るコマンドもあるので確認してみるといいかも。

// logの確認
systemctl status [servie ファイル名]

// タイマー登録されているサービスを全て確認
systemctl list-timers

.shや実行ファイルに実行許可があるか確認したりとか。

// パーミッションの確認
ll [ファイル名]

// 実行許可
chmod +x [ファイル名]

ちなみに動作確認はしていないがserviceが自動起動するようにもできるみたい。

// 自動起動
systemctl enable [timer ファイル名]

// 自動起動を止める
systemctl disable [timer ファイル名]

// 自動起動がenableか確認する
systemctl list-unit-files --no-pager | grep [timer ファイル名]