systemctl - systemdやサービスの制御を行う

スポンサーリンク

systemctlコマンドはsystemdやサービスマネージャの状態を確認でき、制御を行うことができます。
systemdはLinuxでのinitシステムの一つで、多くのLinuxディストリビューションではデフォルトで利用されています。
systemdはユニットファイルを利用して、サービスの制御をします。ユニットファイルを自作することもできますが、
インストールしたパッケージのサービスを利用する場合、基本的にsystemdのユニットファイルもインストールされるので、そのユニットファイルを利用して、systemctlコマンドでsystemdに対してそのサービスを起動させたり、自動起動の設定を行なったりできます。

目次

スポンサーリンク

デフォルトのターゲットを確認(systemctl get-default)

systemctl get-defaultはデフォルトのターゲットを確認することができます。
デフォルトのターゲットはマシンが起動するときに始めに読み込まれるsystemdのユニットファイルになります。
基本的に最初にデフォルトのターゲットで設定されているのはシステムサービスではgraphical.targetまたはmulti-user.targetであり、GUI環境ではgraphical.targetで、CUI環境ではmulti-user.targetになっていることが多いです。
コマンド例と実行結果

.targetファイルはユニットをグループ化したり、ユニットの同期ポイントとして利用されます。
graphical.targetは"Requires="でmulti-user.targetを依存関係として同時に起動するように要求して、
"After="でユニットの起動順としてmulti-user.targetの後にgraphical.targetが起動するようにされています。

graphical.target(#で始まる行はコメント)

multi-user.target(#で始まる行はコメント)

systemdにはユーザーのログイン時に起動するユーザーサービスのためのデフォルトのターゲットも存在します。これは--userをつけることで確認できます。こちらはデフォルトの設定だとdefault.targetとなっています。

default.target

 

 

 

サービスの状態を確認(systemctl status)

systemctl statusはsystemdによって管理しているサービスの状態を確認することができます。
以下の例はnginxのサービス状態を確認したものになっています。

コマンド例と実行結果

 

 

 

 

ユニットファイルの内容を確認(systemctl cat)

systemctl catはユニットファイルの内容を確認することができます。
また、最初の一行目にそのファイルの場所がコメントのように追加されるのが特徴的です。

コマンド例と実行結果

 

 

 

ユニットファイルのパラメータを確認(systemctl show)

systemctl showはユニット、ジョブ、マネージャのパラメータを表示できます。
引数がない場合は、マネージャのパラメータを表示します。
例では表示される項目が多いため、最初の3行を表示しています。

コマンド例と実行結果

 

 

 

ユニットファイルのドキュメントを表示(systemctl help)

systemctl helpはユニットファイルに設定されているドキュメントを開くことができます。

コマンド例と実行結果

 

 

 

サービスの起動(systemctl start)

systemctl startでサービスを起動できます。

コマンド例と実行結果

 

 

 

サービスの停止(systemctl stop)

systemctl stopでサービスを停止できます。

コマンド例と実行結果

 

 

 

サービスの設定ファイルを再読み込み(systemctl reload)

systemctl reloadは指定したサービスが利用している設定ファイルを再読み込みすることができます。つまり、nginxのnginx.confやApacheのhttpd.conf等の設定ファイルを再読み込みできます。

コマンド例と実行結果

 

 

 

サービスの自動起動の設定(systemctl enable)

systemctl enableはサービスの自動起動を出来るようにします。自動起動を設定するとLoadedの単純にdisabledになっている部分がenabledに変更されます。

コマンド例と実行結果

自動起動の設定について、ユニットファイルのInstallセクションのWantedByの項目でsystemdに対してその項目と同時に起動するように要求します。
しかし、nginxはUnitセクションにAfterが設定されているため、自動起動をするときはそのタイミングまで起動を待ちます。

systemctl enableは即時に起動させるコマンドではないため、自動起動の設定と同時に起動も行いたい場合は--nowオプションと同時に利用するか、その後にsystemctl startを行う必要があります。

または

自動起動の設定と同時にサービスも起動

 

 

 

 

サービスの自動起動の設定の解除(systemctl disable)

systemctl disableはsystemctl enableとはほぼ逆のコマンドになり、サービスの自動起動の設定の解除を行うことができます。

コマンド例と実行結果

こちらもsystemctl enableと同様にサービスを停止させるコマンドではないため、同時にサービスの停止も行いたい場合は--nowオプションと同時に利用するか、その後にsystemctl stopを行う必要があります。

または

自動起動の設定の解除と同時にサービスの停止

 

 

 

 

ユニットファイルの再読み込み(systemctl daemon-reload)

systemctl daemon-reloadはユニットファイルの再読み込みを行って、systemdで管理している依存関係ツリーを再構築します。
systemdの管理しているユニットファイルとディスク上のユニットファイルに差が出ている場合に必要になります。
例えば、systemdの管理しているユニットファイルとディスク上のユニットファイルに差が出る例として、自動起動させているユニットファイルを編集するとこのコマンドが必要になるでしょう。
また、その場合だったら、systemctl daemon-reloadを実行するように注意文が出ます。

コマンド例と実行結果

 

 

 

ユニットファイルのリストを確認(systemctl list-units等)

systemctl list-unitsはsystemdが現在メモリ内に持っているユニットのリストを確認できます。
例では行数が多かったため、最初の3行だけ表示しています。

コマンド例と実行結果

他にも、list-automounts, list-sockets, list-timersもあります。

 

 

 

ユニットファイルの依存関係のリストを確認(systemctl list-dependencies)

systemctl list-dependenciesはユニットファイルの依存関係のリストを確認できます。
引数を省略するとdefault.targetが指定されます。
例では行数が多かったため、最初の3行だけ表示しています。

コマンド例と実行結果

--userをつけると違うユーザーサービスの別の依存関係を確認することができます。

 

 

 

 

ユニットファイルの検索パス

ユニットファイルの検索パスは以下のmanページで確認できます。

よく見るパスとしてはシステムのサービスマネージャだと

で、ユーザーのサービスマネージャだと

かもしれません。

 

 

 

ユニットファイルを作成してユーザーサービスを起動

ここでは試しにシステムサービスではなくユーザーサービスを作成してみます。
単純なpythonプログラムのサービスを起動させるユニットファイルを作成して、その後、自動起動の設定を追加して行いたいと思います。
pythonプログラムは起動時の時間を覚えておき、5秒ごとに起動時までの経過した時間を表示する単純なプログラムになっています。

自動起動を行わないサービスの作成

まず自動起動を行わないユニットファイルを作成してみます。
作成する場所は~/.config/systemd/userとし、ファイル名はmyapp-sleep-print.serviceとします。

 

 

 

サービスに利用するプログラムを作成

pythonプログラムの方は以下のようになります。プログラムを作成した後は実行権限を付与することを忘れないようにしましょう。保存している場所は~/myappになり、ファイル名はsleep_print.pyになります。起動するプログラムは上のExecStartのパスと合わせましょう。また、ExecStartでパスを書く場合は基本的にフルパスである必要があります。

sleep_print.py

標準出力はsystemdで起動された場合、デフォルトではsystemdのロギングサービスのjournaldに渡されます。

簡単にプログラムの気になる点を解説します。
・print関数のflush=Trueは、文字の出力をバッファリングせずに即時に出力するために入れています。flush=Trueがないと文字の出力はバッファリングされ、journaldのログを確認しているときにプログラムの動作のタイミングと文字の出力の動作のタイミングが異なる感じになり、期待したタイミングで文字が出力されなくなる場合があります。
・signalの部分は、systemdがサービスを停止する場合、デフォルトではsystemdがそのサービスに対して、SIGTERMが送り、さらにその後にSIGKILLが送るそうですが、pythonプログラムはSIGTERMが送られるとtry-finallyのfinally部分を実行せずにプロセスを終了するそうなので、SIGTERMのシグナルをキャッチしたら、自分でプログラムを終了するような形にしてfinally部分が動作するようにしています。

print関数のflush=Trueが面倒なときは以下のようにprint関数をオーバーライドしてもいいかもしれません。

 

 

 

サービスの起動と停止

ユニットファイルとプログラムを作成したら、

で起動できます。

サービスを停止する場合は

で停止することができます。

起動してから、20か30秒ぐらい経過した後に停止させた後にsystemctl statusを見ると以下のようなログを見ることができます。

また、GUI環境などではもう一つ端末を開いて、

とするとリアルタイムでログを確認することができます。

 

 

 

自動起動の設定

Installセクションを追加します。ユーザーサービスなので、WantedByにdefault.targetを指定します。これがシステムサービスならば、graphical.targetやmulti-user.target等を指定するかもしれませんが、ユーザーサービスではそれらのシステムサービスのユニットファイルを指定できません。

補足として、default.targetはユーザーサービスでユーザーログイン時に始めに読み込まれるユニットファイルになります。

ユニットファイルができたら、systemctl enableで自動起動を設定します。

ログアウトを行なって、再度ログインを行うと起動していることが確認できます。

 

 

 

サービスの停止と自動起動の設定を解除

最後に、今回試しに作ったサービスを停止し、また、このサービスは特に何も役に立たないので、自動起動の設定を解除して終わりにします。

 

 

 

タイマーのユニットファイルを作成して定期的にサービスを実行

タイマーのユニットファイルを作成すると定期的にサービスを実行することができます。
システムサービスでもタイマーで定期的にサービスを実行できますが、ここでは、試しにユーザーサービスでタイマーのユニットファイルを利用してみます。

タイマーで利用するサービスやプログラムを準備

タイマーで定期的に実行させるサービスは以下のようなものです。

また、利用するプログラムは以下のようなものになります。

~/myapp/rand_print.py

このプログラムをsystemctl startで起動させて、

その出力結果をjournalctlで確認すると以下のような感じになります。

 

 

 

タイマーのユニットファイルを作成と起動の確認

タイマーのユニットファイルは以下のようになります。

OnBootSecでまずマシンが起動してから5秒後にタイマーがサービスを1回起動させます。既に過ぎていた場合はタイマーはすぐにサービスを起動させます。その後のOnUnitActiveSecでタイマーがサービスを起動させた後の10秒後にまたタイマーがサービスを起動させます。こちらも既に過ぎていた場合はすぐに起動になります。

TimerセクションのUnitの指定はここでは必要ありませんが明示しています。これがない場合、タイマーが起動するサービスは同名のサービスのユニットファイルが指定されます。

タイマーのユニットファイルが作成出来た後は、自動起動を有効にします。

ユーザーサービスの起動タイミングはログイン時なので、一度ログアウトしてからもう一度タイマーのユニットファイルをsystemctl statusで確認すると起動していることが確認できます。

その後、ある程度時間が経過した後にjournalctlでログを確認すると以下のようなログを確認できます。

う~ん、微妙に精度が悪いですね。

 

 

 

時間の精度を細かくして再確認

調べてみるとTimerセクションのAccuracySecでタイマーの精度を設定できるそうです。デフォルトでは1分毎になっているので今回のものではタイマーの定期実行する時間の設定が短すぎたようです。
AccuracySecは電力消費を最適化するためにCPUのウェイクアップを抑えるために利用するそうです。今回は試しなのでこの時間精度の間隔を長くするのではなく、50msまで短くしたいと思います。

ユニットファイルを編集したので、

をした後にタイマーをsystemctl startで起動させ、何十秒間待った後にjournalctlで確認してみます。

今度は良い感じのタイミングで定期的に実行しています。

 

 

 

サービスの停止と自動起動の設定の解除

最後に、今回試しに作ったサービスを停止して自動起動の設定を解除して終わりにします。

 

 

 

参考

systemctl

systemd/タイマー - ArchWiki

ユニットファイルについては以下のmanページがあります。