systemdでツールの自動起動をしてみよう


systemd(システム・ディー)は、Linux OSにおいてシステム全体の起動と、裏で動くプログラム(プロセス)を一元管理する仕組みのツールになります。

System and Service Manager


主にOSの起動後に任意のツールを自動で実行する時に利用します。


OSの起動後に自動で実行する仕組みには、cronの@rebootやXDG自動起動がありますが、これらはOSの起動中に自動実行したツールが異常終了した場合に自動で起動してくれません。

ラズベリーパイで電源を入れた時に任意のアプリケーションを自動起動してみる


その点、systemdは異常終了したツールを再び起動してくれます。

自作ツールを介して、systemdの設定内容を見ていくことにしましょう。




検証用として、自動起動後にすぐにクラッシュするツールを作ってみます。

$ micro crash-text.go
package main

import "log"

func main() {
	log.Println("システム起動!起動後すぐにクラッシュします!")
	panic("クラッシュ!")
}

ファイルを保存して実行してみます。

$ go run crash-test.go
HHHH/MM/DD HH:II:SS システム起動!起動後すぐにクラッシュします!
panic: クラッシュ!

goroutine 1 [running]:
main.main()
	/home/pi/crash-test.go:7 +0x79
exit status 2

実行後すぐにクラッシュしました。




crash-testをコマンドにしてパスを通します。

$ go build crash-test.go
$ mkdir -p ~/.local/bin
$ mv crash-test ~/.local/bin/

利用中のシェルがBashの場合

source ~/.bashrc

利用中のシェルがZshの場合

echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc

$ which crash-test
/home/pi/.local/bin/crash-test



systemdでcrash-testを自動で実行できるようにします。

$ mkdir -p ~/.config/systemd/user
micro ~/.config/systemd/user/crash-test.service

~/.config/systemd/user/crash-test.service

[Unit]
Description=Crash Test Service
After=network.target

[Service]
Type=simple
ExecStart=crash-test
Restart=always
RestartSec=5

[Install]
WantedBy=default.target

ファイルを保存後、OSを再起動すれば自動で実行されますが、下記のコマンドで設定の即時反映と実行をしてみます。

$ systemctl --user daemon-reload
$ systemctl --user enable --now crash-test.service

実行後に

$ systemctl --user status crash-test.service

で設定が有効になっているかを確認します。


● crash-test.service - Crash Test Service
     Loaded: loaded (/home/saito/.config/systemd/user/crash-test.service; enabled; pres>
     Active: activating (auto-restart) (Result: exit-code) since Wed 2026-07-15 14:16:1>
 Invocation: 86b52d4f8e014353b60aa655db999ec0
    Process: 7784 ExecStart=crash-test (code=exited, status=203/EXEC)
   Main PID: 7784 (code=exited, status=203/EXEC)
   Mem peak: 1.7M
        CPU: 11ms

Activeがinactive (dead)になっていなければ良いです。


サービスが有効であることを確認できたら、下記のコマンドでログを確認します。

journalctl --user -u crash-test.service -f

を実行すると

 m月 dd HH:ii:ss *********** (crash-test)[6208]: crash-test.service: Unable to locate executable 'crash-test': No such file or directory
 m月 dd HH:ii:ss *********** (crash-test)[6208]: crash-test.service: Failed at step EXEC spawning crash-test: No such file or directory
 m月 dd HH:ii:ss *********** systemd[3734]: crash-test.service: Main process exited, code=exited, status=203/EXEC
 m月 dd HH:ii:ss *********** systemd[3734]: crash-test.service: Failed with result 'exit-code'.

といったメッセージが5秒毎に出力されます。


Ctrl + cでjournaldの出力を終了し、crash-testの自動起動を終了します。

$ systemctl --user stop crash-test.service
$ systemctl --user disable crash-test.service



crash-test.serviceの解説

[Unit]
Description=Crash Test Service
After=network.target

[Service]
Type=simple
ExecStart=crash-test
Restart=always
RestartSec=5

[Install]
WantedBy=default.target

serviceファイルを理解するために、systemdのtargetについて理解する必要があります。


systemdで自作ツールの自動起動をする時、OSが起動してからどの段階で起動するかを決める必要があります。

この時に大事になるのがtargetになります。


例えば、自作ツールが初期実行でネットワークの処理がある場合、ネットワーク関連のプロセスが実行されている必要があります。

そこでserviceファイルの[Unit]の項目で

After=network.target

のように指定することで、ネットワークが起動された後に自作ツールが実行するようになります。


targetは以下の通りです。

※画像をクリックすると拡大表示します。


network.targetはbasic.targetの後のvarious system servicesに含まれます。


[Service]
Type=simple
ExecStart=crash-test
Restart=always
RestartSec=5

は何のコマンドをどのような条件で実行するかを決めています。

※Typeは省略します。


ExecStartでコマンドの指定を行い、RestartとRestartSecでプロセスが異常終了した際に再起動を何秒毎に試すか決めることができます。


[Install]
WantedBy=default.target

はdefault.targetが起動するときに、今回のサービスを要求することを意味します。


default.targetが何を指しているかの調べ方は、下記コマンドを実行します。

 $ systemctl get-default
graphical.target

のような内容が出力されます。

京都の東本願寺で開催されているプログラミング教室で講師をしています。
詳しくはTera schoolを御覧ください。
同じカテゴリーの記事
マインクラフト用ビジュアルエディタを開発しています。

詳しくはinunosinsi/mcws_blockly - githubをご覧ください。