systemdによる自動起動(Linux) | そう備忘録

systemdによる自動起動(Linux)

systemdによる自動起動

以前にRaspberryPiによる監視カメラのプログラムを作成したのだが、電源オン時のプログラムの自動起動にsystemdを使った。

その時に調べた事を備忘録として記事にしておく。

尚、当方のLinuxの知識及び英語力の不足により曖昧、分からない所が多々あるが備忘録なのでとりあえずそのまま載せているのでご了承ください。(間違いは指摘を頂けると助かります)

試した環境

今回調査した環境は以下の通り。

serviceファイルの設定例

本体

RaspberryPi 3 B+

OS

Raspbian※

  • Version:June 2019
  • Kernel version:4.19

※DebianベースのOS

ユニット設定ファイルの作成

ファイルの種類

最初にプロセスの自動起動の設定を行うためにユニット設定ファイルを作成する。

  • ファイル名:[任意の名前].service
  • 格納場所:/etc/systemd/system/~

プロセスの自動起動には拡張子.serviceのユニット設定ファイルを作成するのだが、serviceの他には下記の種類がある。

.service

systemdによって制御および監視されるプロセスに関する設定

実行環境、プロセスの終了される方法、プロセスのリソースの制御など

.socket

IPC(InterProcess Communication)※やネットワークソケットに関する制御

※プロセス間通信、名前付きパイプ、OLEやDDEなど

.device

デバイスユニットに関する設定

.mount

ファイルシステムのマウントポイントに関する設定

.automount

ファイルシステムの自動マウントポイントに関する設定

.swap

メモリまたはファイルのページング用スワップデバイスの設定

.target

複数のユニットをグループ化して起動時に同期させることができる

.path

パスの監視、認証

監視しているパス(ディレクトリ、ファイル)が変更されたときにアクティブにするユニットを記述することができる

.timer

タイマーによるプロセスの制御

crontabに相当することが出来るのだと思う

2020年11月3日 追記

.timerのタイマー設定について調べた事を「systemd .timerについて」でアップしたので詳しくはそちらを確認して欲しい

.slice

ヘルプには「サービスユニットやスコープユニットなどを階層ツリーでグループ化してリソース管理するために使用する」とあったがイマイチ使い方は理解していない

.scope

ヘルプには「サービスユニットと似ているがプロセスを起動するのではなく外部プロセスを管理する」とあったがイマイチ使い方は理解していない

ファイルの格納場所

ファイルの格納場所は2箇所ある。

/etc/systemd/system/

管理者がカスタマイズする場所

同じファイルが存在する場合はこちらの方が優先になる

/usr/lib/systemd/system/

システムデフォルト

.serviceファイルの設定例

serviceファイルの設定例。

UnitとService、Installの3つのセクションを指定してる。

尚、詳しいオプションはこちらのページを参照

[Unit]
Description = Security Camera
After=network-online.target

[Service]
ExecStart=/usr/bin/python /opt/security-camera/SecCamera.py
Restart=always
Type=simple

[Install]
WantedBy=multi-user.target

Unitセクション

プロセスの説明や依存関係、起動順序などを設定するセクション。

いつも思うのだがLinuxのコマンドは指定可能なオプション数が非常に多い。

Unitセクションにも多数のオプションが指定出来るのだが、通常良く使うのは

  • Description
  • After(Before)
  • Requires

辺りなのでとりあえずその3~4つを抑えておけば良いと思う。

主なオプション

主なオプションは以下の通り。

Description=

説明文

Documentation=

このユニットのドキュメントのURI

スペースで区切って

  • http://
  • https://
  • file:
  • info:
  • man:

が指定可能

After=

起動順序の指定、複数行指定する事ができる

ここで指定したユニットの後に実行される

またシャットダウン時には逆の順番で停止される

例)unit BでAfter=Aを指定した場合、

起動時はA→Bの順番で起動される

シャットダウン時にはB→Aの順番で停止される

Before=

起動順序の指定、複数行指定する事ができる

ここで指定したユニットの前に実行される

Wants=

依存関係を表す

ここで指定したユニットが必要でそのユニットが起動に失敗しても自分は起動する点が下記のRequiresとは異なる

Requires=

依存関係を表す※

ここで指定したユニットが必要でそのユニットが起動に失敗すると自分も起動しない

※依存関係はAfterやBeforeの様な順序関係ではないので同時に並列で起動しようとする

systemdはなるべく並列でユニットを起動してシステム全体の起動時間を短縮する設計になっている

Requisite=

Requiresと似ていて依存関係を表すが、ここに指定されているユニットが起動されていない場合は起動されずにエラーになる

つまり依存関係と順序関係を同時に表すのだが順序を保証する訳ではないので別途Afterと組み合わせて指定する必要がある

RequiresでAfterを指定するのと同じ意味の様に思うのだが詳細は良く分からなかった

BindsTo=

Requiresと似ていて依存関係を表すが、こちらの依存関係の方が強力

BindsTo=で指定されたユニットが何らかの理由で(後から)非アクティブになった時にこのユニットも停止する

例えばデバイスユニットのデバイスが抜かれたりマウントユニットでアンマウントされた時に非アクティブを検知してユニットを停止する様な使い方をする模様

またAfterとの併用が推奨されていて、バインド指定されているユニットがアクティブにならないとこのユニットもアクティブにならない

PartOf=

Requiresと似ていて依存関係を表すが、ユニットの停止や再起動に限定される

systemdがPartOfに指定されているユニットを停止または再起動するとそのアクションがこのユニットに伝えられて停止する(のだと思う)

このユニットへの変更は指定されているユニットには影響せずに一方向の依存関係

Conflicts=

逆の依存関係を表す

つまりConflictsで指定されたユニットを起動するとこのユニットが停止をする

またその逆も同様なので同時に起動したくないユニットを指定する

この設定は順序を保証する訳ではないのでAfterまたはBeforeで順序の依存関係は別に指定する必要がある

OnFailure=

このユニットが「失敗状態」になった時に起動するユニット(スペースで区切って複数指定可能)を指定する

エラー時の後片付け処理等で利用すると思われる

後述のRestart(自動再起動の指定)を指定した場合は開始制限に達した場合に「失敗状態」と判定される

Restart=always(常にプロセスを再起動)を指定している場合には失敗状態にはならないと思われる(未検証)

OnFailureJobMode=

上記のOnFailureで指定されたユニットがどのようにしてエンキュー(実行待ち)されるかを指定する

fail

保留中のジョブと競合する場合はエンキューが失敗する可能性がある

replace

デフォルト

競合する保留中のジョブは必要に応じて置き換えられる

replace-irreversibly

replaceと同様に動作するが新しいジョブは不可逆的なジョブとして記録される

これにより将来競合するトランザクションがこれらのジョブを置き換えることを防ぐことができる

不可逆ジョブはcancelコマンドでキャンセル可能

isolate

指定されたユニットの起動時に他の全てのユニットを停止させる

この為、OnFailureでユニットが一つだけ指定されている時に有効なオプションとなる

flush

OnFailureで指定されたジョブがエンキュー時にキューに入っているすべてのジョブがキャンセルされる

ignore-dependencies

すべてのユニットの依存関係が無視されて直ちに実行される

主に管理者やデバッグ用のオプションでアプリケーションでは指定すべきでは無い

ignore-requirements

ignore-dependenciesに似ているがRequires等の依存関係は無視されるが順序の依存関係は守られる

基本的にはignore-dependenciesと同様にデバッグ時のオプションだと思う

PropagatesReloadTo=、ReloadPropagatedFrom=

リロード要求を別のユニット(スペースで区切って複数指定が可能)に伝搬させる(To:伝搬先、From:伝搬元)

あるユニットに対してリロード(再読み込み)要求をすると伝搬先のユニットに対してもリロード要求が発行される

基本的にはユニットの内容を変更した際にはリロードが必要になるので強い相互依存関係があるユニット同士で指定をするパターンなのかも知れない(良く分かっていない)

JoinsNamespaceOf=

正直良く分からなかった

「ネットワークや一時ファイルの名前空間に参加する他のユニットを指定する」とあった

execセクションで

  • PrivateNetwork=
  • NetworkNamespacePath=
  • PrivateTmp=

を指定するユニットタイプの時に有効になる模様

RequiresMountsFor=

絶対PATH(スペースで区切って複数指定が可能)を指定する

PATH先とはRequiresとAfterの順序依存関係が自動的に設定される

このユニットが動作するために必須になるマウント先をしていするのだと思う

IgnoreOnIsolate=

trueの場合、他のユニットを分離(isolate)する際にこのユニットを停止しないとの事

systemctl isolateコマンドでターゲットを指定して起動した場合、そのターゲットと依存関係のあるユニット以外は全て停止して起動される

その際にtrueで指定されているユニットは停止しない、との意味なのかも知れない(自信なし)

service、target、socket、timer、pathユニットでのデフォルトはfalse

slice、scope、device、swap、mount、automountユニットでのデフォルト値はtrueになる

AllowIsolate=

true の場合(デフォルトはfalse)このユニットは systemctl isolate コマンドで起動することができる

systemctl isolate このユニット(ターゲット)

上記のコマンドでこのユニット(やターゲット)を起動すると指定したユニットとそのユニットに依存するユニット以外は全て停止してから起動される

StopWhenUnneeded=

正直良く分からなかった

true の場合(デフォルトはfalse)ユニットは使用されなくなったときに停止するとあった

「使用されなくなった時」英文だとwhen it is no longer used.がどの様な状態なのかがいまいち分かっていない

RefuseManualStart=、RefuseManualStop=

true の場合(デフォルトはfalse)ユニットは間接的にのみ起動または停止することができる

startやstopコマンドで直接起動、停止しようとしてもエラーになり、他のユニットの依存関係としてのみ起動、停止が可能になる

使い方としては誤ってこのユニットの起動、停止をしないようにする為の安全機能としてのオプションとの事

DefaultDependencies=

true の場合(デフォルトはtrue)このユニットの依存関係がデフォルトで作成される

例えばserviceユニットの場合は基本的なシステムの初期化が完了した後にのみサービスが開始され、システムのシャットダウン時に適切に終了することが保証される

余程の理由が無い限りtrueのままにして置くほうが良いと思う

CollectMode=

ガベージコレクション(不要になったメモリーを自動的に開放する仕組み)の指定

  • inactive(デフォルト)
  • inactive-or-failed

の2種類の指定が可能でinactiveを指定するとユニットが非アクティブ状態でクライアントやジョブ、他のユニットから参照されない場合にアンロードされるがfailed状態の場合はsystemctl reset-failedコマンドで失敗状態をリセットするまでアンロードされない

inactive-orfailedを指定すると、このユニットがfailed状態であってもアンロードされるので、明示的にリセットする必要が無い

ただ自動的にリセットされるとユニットの結果(終了コード、終了信号、消費されたリソースなど)は消えてしまうので注意

FailureAction=、SuccessAction=

ユニットが停止して非アクティブまたはfailed状態になったときに実行するアクションを指定する

  • none(デフォルト)
  • reboot
  • reboot-force
  • reboot-immediate
  • poweroff
  • poweroff-force
  • poweroff-immediate
  • exit
  • exit-force.

のいずれかが実行可能

システムモードではすべてのオプションが指定可能だがユーザーモードではnone、exit、exit-forceのみが指定可能

尚、SuccessActionの方は成功した時に実行するアクションの指定

FailureActionExitStatus=、 SuccessActionExitStatus=

上記のFailureAction、SuccessActionでexitまたはexit-forceが指定されている時に有効

起動コンテナマネージャやサービスマネージャに返す終了ステータスを0~255の数値または空白で指定する

未指定の場合は起動したユニットのメインプロセスの終了ステータスが返される

JobTimeoutSec=、JobRunningTimeoutSec=

JobTimeoutSecはキューイング時のタイムアウトの指定

JobRunningTimeoutSecは実行中のジョブ(実行時間)のタイムアウトの指定を行う

制限時間を超えた場合はジョブはキャンセルされるがfailed状態になることはない

デフォルトは無限大

また紛らわしいのだが後述のServiceセクションで指定可能なTimeoutStartSecのタイムアウトとは別との事

「このオプションで設定されたジョブタイムアウトはユニットの状態変化を待っているジョブのみを中止するのに便利」とあるが違いはイマイチ理解していない

JobTimeoutAction=、JobTimeoutRebootArgument=

上記のJobTimeoutAction、JobRunningTimeoutSecオプションでタイムアウトが発生したときに実行する追加のアクションを指定する

デフォルトはnone(何もしない)

StartLimitIntervalSec=interval、StartLimitBurst=burst

ユニットの起動回数制限を設定する

interval時間内にburst回数を超えて起動されたユニットはそれ以上の起動を許可しない

デフォルト値はマネージャ設定ファイル※のDefaultStartLimitIntervalSec、DefaultStartLimitBurstに設定されており、ここでの指定で上書きされる

※設定ファイルはラズパイ(Raspbian)では /etc/systemd/system.confにありデフォルト値は10sと5( 10秒間に5回まで)となっていた

後述するServiceセクションのRestartと一緒に使用すると有効

systemctl reset-failedコマンドや前述のガベージコレクションでアンロードされるとカウントはリセットされる

StartLimitAction=

上記のStartLimitIntervalSec、StartLimitBurstで起動回数制限に達した時に実行するアクションを指定する

前述のFailureAction、SuccessActionと同じ設定値が使用可能

デフォルトはnone(何もしない)

RebootArgument=

StartLimitActionやFailureActionがrebootの時のオプション引数を指定する

SourcePath=

正直良く分からなかった

「このユニットが生成した設定ファイルへのパス」との事

「この機能は通常のユニットでは使用しないでください」とあった

ユニットの起動順序を表示するコマンド

プロセスを起動したい時は”何々の後(After)で起動する”が一番よく使うパターンだと思う。

しかしAfterでどのユニットを指定すべきなのかがイマイチ分からなかった。

その際には以下のコマンドで現在のユニットの起動順序が表示される。

sudo systemctl list-dependencies
RaspberryPi  3 B+(Raspbian)での実行結果
systemctl list-dependenciesの結果

afterの指定は上記画面ショット中の”multi-user.target”を指定するパターンが一般的な模様。

Serviceセクション

Serviceセクションでの指定可能なオプションは以下の通り。

非常に数が多く、どれを指定すれば良いのかがイマイチ良く分からないが頻繁に使用するオプションは

  • ExecStart
  • Type
  • Restart

辺りが多い。

尚、詳細はこちらのページを参照

Type=

プロセスの起動タイプ、ユニット開始の判断基準を表している

以下の種類がある

simple

通常のプロセス

プロセスが開始した時※にユニットが開始したとみなす

※fork()で自分自身のプロセスをコピーして子プロセスの生成が成功した時

exec

simpleに似ているがexecve()※が成功した時に開始したとみなす

※execve()で実行ファイルを実行する

fork()→execve()で新しいプロセスが実行される

fork()が成功するがexecve()で失敗するのはuser=で指定したユーザが見当たらない、実行バイナリが見つからない等のケースがある模様

forking

最初に起動した親プロセスから子プロセスをバックグラウンドで起動して親は終了する様な起動パターンの時に親プロセスが終了した時点でユニットが開始したとみなす

oneshot

simpleに似ているがメインプロセスが終了した後でもユニットが稼働しているとみなす

後述のRemainAfterExitと一緒に指定する

idle

正直イマイチ理解していない

simpleに似ているがサービスプログラムの実際の実行はすべてのアクティブなジョブがディスパッチされるまで遅延するとの事

コンソール出力があるシェルの実行の時に使用されて、シェルからのコンソール出力とステータス出力が混在するのを避けるために使用される模様

その他

その他にはdbus、notifyなどが設定可能な模様

正直Linux及び英語力が及ばず違いがよく理解できなかった

RemainAfterExit=

Yesとすると全てのプロセスが終了していてもサービスをアクティブとみなす

デフォルトはno

GuessMainPID=

type=forking、PIDFile(下記参照)が設定されている時に有効

YesだとメインのPIDが確実に決定できない場合に、systemdがサービスのメインPIDを推測する

デフォルトはYes

デーモンが複数のプロセスで構成されている場合は誤った推測をする事もあるらしく「メインPIDを特定できない場合は障害検出とサービスの自動再起動は機能しない」とあるのでYesにしていても推測に頼るのは若干危険なのかも知れない

type=forking以外の時はメインPIDは常に分かっているので無視される

PIDFile=

PIDファイル(プロセスIDを格納するファイル)へのパスを指定する

type=forkingの時は指定を推奨との事

指定されたパスは通常 /run/配下のファイルを指す

また相対パスが指定された場合は/run/がプレフィックスとしてつくとの事

BusName=

正直良く分からなかった

D-Bus(アプリケーション間でやりとりを行うためのプロセス間通信)利用時のデスティネーション名との事

ExecStart=

プロセスを起動するコマンドを指定する

尚、特殊な接頭文字(”@”、”-“、”:”、”+”、”!”、”!!”)を指定することで特権で起動したり、arg[0](実行ファイル名が格納されている)を置き換えたりする事ができる

ExecStartPre=、ExecStartPost=

ExecStartの前/後(pre/post)に実行するコマンドを指定する

つまり

  1. ExecStartPre
  2. ExecStart
  3. ExecStartPost

の順番で起動される

構文はExecStartと同じだが、

  • 複数のコマンド行が許可される
  • コマンドが次々に順番に実行される

点が異なる

コマンドのいずれかが失敗した場合は残りは実行されずユニットは失敗したと見なされる(ExecStartPreが失敗した時はExecStartは実行されない)

ExecStartPostのコマンドはExecStartのプロセスが正常に起動された後にのみ実行される

ExecCondition=

ExecStartPreの前に実行される条件分岐させる為のコマンド

構文はExecStartと同じだが、

  • 複数のコマンド行が許可される
  • コマンドが次々に順番に実行される

点が異なる

ExecStartPreの前の条件チェックの様な動作をする

ExecConditionのコマンドの終了コードが0またはSuccessExitStatusに一致する場合は実行を継続する

ExecConditionのコマンドの終了コードが1~254の時は残りのコマンドはスキップされるがユニットは失敗とはみなされない

ExecConditionのコマンドが255で終了や異常終了した場合は残りのコマンドがスキップされてユニットは失敗とみなされる

ExecReload=

サービスの再読み込みをするコマンドを指定する

構文はExecStartと同じ

ExecReload=kill -HUP $MAINPID

上記の様な指定は良い方法では無いとの事

ExecStop=

ExecStartで開始したサービスを停止するためのコマンド

ここでの指定はサービスが最初に正常に起動した時にのみ実行されることに注意する

サービスの起動に失敗した場合にも実行したい場合は下記のExecStopPostを利用する

ExecStopPost=

サービスが停止後に実行するコマンド

前述のExecStopでの停止やサービスの異常終了時も含まれる

またサービスの正常な起動が失敗したときにも呼び出されるのでクリーンアップ(不要ファイルなどの削除)等にも利用できる

RestartSec=

サービスを再起動する前にスリープする時間

デフォルトは100ミリ秒

TimeoutStartSec=

起動までのタイムアウトの時間の指定

指定時間内にサービスが起動しないと起動失敗とみなす

TimeoutStopSec=

ExecStopでサービスを停止したときのサービス終了までのタイムアウトの時間の指定

指定時間内にサービスが終了しないとSIGKILLにより強制的に終了させる

TimeoutAbortSec=

ウォッチドッグ(※)タイムアウトでサービスが停止した時にサービスが終了するまで待機する時間を指定

※システムが正常に動作しているかどうかを監視するため仕組み

上記のTimeoutStopSecが短い場合にこのオプションを使用してコアダンプを書き込む時間をシステムに与えたりする

TimeoutSec=

TimeoutStartSecとTimeoutStopSecを同時に同じ値を設定する時にこのオプションで設定ができる

TimeoutCleanSec=

systemctl clean(指定されたユニットのキャッシュ、ログ、ランタイムデータの削除をするコマンド)を実行した時のタイムアウト時間の設定

※最新のマニュアルには無いので無くなってしまったのかも知れない

TimeoutStartFailureMode=、 TimeoutStopFailureMode=

前述のTimeoutStartSecやTimeoutStopSecでタイムアウトになった時のアクションを指定する

  • terminate(デフォルト)
  • abort
  • kill

が指定可能

terminateを指定した場合はサービスはKillSignal(※デフォルトはSIGTERM)を送信して終了する

それでもサービスが終了しない場合はTimeoutStopSecで指定された時間の後にFinalKillSignal(※)が送信される

abortを指定した場合はWatchdogSignal(※)が送信されてFinalKillSignal(※)を送信する前にTimeoutAbortSecが適用される

killを指定した場合はFinalKillSignal(※)を送信してタイムアウトなしに直ちに終了する

killは失敗したサービスのシャットダウンを迅速化するために使用する模様

※KillSignal、FinalKillSignal、WatchdogSignalはkillセクションで指定できる

RuntimeMaxSec=

サービスを実行する最大時間の設定

この時間を過ぎるとサービスは終了する

尚、前述のTypeでoneshotを指定した時は無効になる

実行時間を制限したくない場合はinfinity(デフォルト)を設定する

WatchdogSec=

ウォッチドッグタイムアウトを設定する

ウォッチドッグ(番犬)はサービス等を定期的に監視して稼働状態をチェックする為の機能

上記時間内に稼働が確認されないとタイムアウトとなり非稼働とみなされる

Restart=

サービスプロセス停止時の再起動条件の設定

always

常に再起動される

on-success

サービスプロセスが正常に終了した時のみ再起動される

on-failure

サービスプロセスが正常終了以外の時に再起動される

  • 終了コードがゼロでない
  • SIGHUP、SIGINT、SIGTERM、SIGPIPE以外のシグナルで終了
  • タイムアウト
  • ウォッチドッグタイムアウト

on-abnormal

on-failureに近いが”終了コードがゼロでない”は除く

  • SIGHUP、SIGINT、SIGTERM、SIGPIPE以外のシグナルで終了
  • タイムアウト
  • ウォッチドッグタイムアウト

on-abort

クリーンなシグナル以外で終了した時に再起動

  • SIGHUP、SIGINT、SIGTERM、SIGPIPE以外のシグナルで終了

on-watchdog

ウォッチドッグタイムアウトの時に再起動

  • ウォッチドッグタイムアウト

尚、systemctl stopで停止された場合は再起動しない

またRestartPreventExitStatusで終了コードやシグナルが指定されている時も再起動しない

逆に RestartForceExitStatusで終了コードやシグナルが指定されている場合は常に再起動される

SuccessExitStatus=

通常の正常終了コード0とシグナルSIGHUP、SIGINT、SIGTERM、SIGPIPEに加えて正常終了とみなす終了コードのリストを指定する(半角スペース区切り)

例)

SuccessExitStatus=250 SIGKILL

※終了コード250とSIGKILLは正常終了と見なす

RestartPreventExitStatus=

Restart=の再起動の指定に関係なく、ここで指定された終了コードとシグナルは再起動しない(半角スペース区切り)

例)

RestartPreventExitStatus=16 SIGABRT

※終了コード16とSIGABRTはRestartの指定に関わらず再起動しない

RestartForceExitStatus=

Restart=の再起動の指定に関係なく、ここで指定された終了コードとシグナルは常に再起動する(半角スペース区切り)

RestartPreventExitStatus=16 SIGABRT

※終了コード16とSIGABRTはRestartの指定に関わらず再起動する

RootDirectoryStartOnly=

Trueの時はsystemd.execで指定したRootDirectory=(実行するプロセスのルートディレクトリの指定)がExecStart=のみに有効

Falseの場合はすべてのコマンドに有効、との記述だがイマイチ使い方が分からない・・・

OOMPolicy=

Out-Of-Memory (OOM) キラーポリシーを設定する

OOM Killerとはメモリが枯渇した時にシステムの動作を確保するためにメモリを多く使用しているプロセスを次々と停止(kill)する仕組み

  • continue
  • stop
  • kill

が指定可能

continue(デフォルト)を指定するとこのサービスがOOM Killerによって停止された際にログに記録された上でサービスの実行は継続される

stopを指定した場合はログに記録されてサービスは終了する

killを指定した場合はカーネルはサービスの残りのプロセスを停止する(ログに書かないと思われる)

その他

その他にはNonBlocking=、NotifyAccess=、Sockets=、FileDescriptorStoreMax=、USBFunctionDescriptors=、USBFunctionStrings=のオプションがあるが当方の英語力、Linuxへの理解度では歯が立たなかった・・・

User=

実行ユーザを指定する

Group=

実行グループを指定する

Installセクション

Installセクションはsystemdからは解釈されずに後述のsystemctl enable、disable(サービスの自動起動)で使用される。

Alias=

エイリアス名

a.serviceにてAlias=b.serviceを指定するとb.serviceでも参照できる

WantedBy=、RequiredBy=

ユニットの依存関係を表す

前述のRequires、Wantsと同様の機能(だと思う)

違いはsystemctl enable時に指定したユニット名.wants、.rewuiresに自ユニットへのシンボリックリンクを作成して指定したユニットが起動される時に自ユニットを起動させる

よくある指定例としては、

WantedBy=multi-user.target

WantedBy=graphical.target

を指定する

Also=

systemctl enable、disable時に同時にenable、disableするユニットを指定する

DefaultInstance=

インスタンスを明示的に設定せずにテンプレートを有効にした場合に有効になるインスタンスを指定する

テンプレートユニットとはaaa@.serviceというテンプレートユニットファイルを設定すると、

  • aaa@bbb.service
  • aaa@ccc.service

等の複数サービスの設定ファイルとして機能する

  • aaa:プレフィックス
  • bbb、ccc:インスタンス(任意の文字列)

systemctlコマンド

ユニット設定ファイルを作成した後、以下のコマンドが利用できる。

サービスの起動

サービスを起動する時に使用する(※OS起動時に自動起動されるわけではない)

systemctl start [ユニット名]

サービスの停止

サービスを停止する時に使用する。

systemctl stop [ユニット名]

サービスのステータス確認

サービスのステータスを確認する時に使用する。

systemctl status [ユニット名]

最初にユニットファイルを作成した時はstartコマンドでサービスを開始した後にstatusでステータスを確認してみる。

正常に稼働していれば、下記の様にステータスがactiveと表示される。

ステータスがactive

何らかの理由で起動が失敗している場合は下記のログを見てみる。

  • /var/log/syslog
  • /var/log/message

「権限が無い」「スペルを間違えた」「ExecStart=の構文が間違っている」等の理由が多い気がする。

アクティブかの確認

サービスがアクティブかどうかを確認する。

statusコマンドと比べてシンプルな実行結果が表示される。

systemctl is-active [ユニット名]

実行結果

is-active実行結果

サービスの再起動

サービスの再起動。

停止後、起動する。

systemctl restart [ユニット名]

サービスのリロード

サービスのリロード。

サービスを停止せずに再読み込みをする。

systemctl reload [ユニット名]

尚、サービスにリロードする機能があるかどうが分からない場合はreload-or-restartコマンドが使える。

リロードを試みて駄目な場合は再起動を行う。

自動起動の有効化

サービスの自動起動を有効化する。

OS起動時に自動的に起動させたいサービスに使用する。

systemctl enable [ユニット名]

自動起動の無効化

サービスの自動起動を無効化する。

systemctl disable [ユニット名]

自動起動設定の確認

サービスの自動起動が有効になっているかを確認する。

systemctl is-enabled [ユニット名]

デーモンリロード

systemdマネージャー構成をリロードする。

これによりすべてのジェネレーターが再実行されリロードされる。

.serviceファイルを修正した場合は変更を反映させる為にリロードする。

systemctl daemon-reload

サービス一覧(アクティブのみ)

現在システムでアクティブになっているすべてのユニットのリストが表示される。

systemctl list-units
実行結果
list-units実行結果

UNIT

ユニット名

LOAD

LOADされているかどうか

ACTIVE

Activeかどうか

SUB

ユニットの詳細情報

Typeによって異なる模様

DESCRIPTION

説明

サービス一覧(すべて)

-allで現在のシステムでの状態に関係なくロードしようとした全てのユニットのリストが表示される。

systemctl list-units --all

サービス一覧(非アクティブ)

–stateで状態を絞り込む。

非アクティブなユニットのリストが表示される指定例。

systemctl list-units --all --state=inactive

サービス一覧(ロードしようとしてないユニットも含む)

list-unitsはロードしようとしたユニットのみを表示する。

list-unit-filesはシステム上で利用可能な全てのユニットを表示する。

systemctl list-unit-files

サービス一覧(全てのサービス)

以下のコマンドで全てのサービスを表示する。

恐らく一番使うパターン。

systemctl list-unit-files --type=service
実行結果
list-util-files実行結果

以上でsystemdについて調べた時の備忘録を終了する。

最後に

この記事が何処かで誰かの役に立つことを願っている。

尚、当記事中の商品へのリンクはAmazonアソシエイトへのリンクが含まれています。Amazonのアソシエイトとして、当メディアは適格販売により収入を得ていますのでご了承ください。

souichirou

やった事を忘れない為の備忘録 同じような事をやりたい人の参考になればと思ってブログにしてます。 主にレゴ、AWS(Amazon Web Services)、WordPress、Deep Learning、RaspberryPiに関するブログを書いています。 仕事では工場に協働ロボットの導入や中小企業へのAI/IoT導入のアドバイザーをやっています。 2019年7月にJDLA(一般社団法人 日本デイープラーニング協会)Deep Learning for GENERALに合格しました。 質問は記事一番下にあるコメントかメニュー上部の問い合わせからお願いします。

おすすめ

9件のフィードバック

  1. 通りすがり より:

    systemdのオプションについて日本語での資料が少ないので助かりました。ありがとうございます。

    • souichirou より:

      通りすがりさん
      コメントをありがとうございます。
      systemdはオプションの数が多い割に日本語の資料が少ないですよね。
      自分の備忘録の為に記事にしておいたのですがお役に立てたようで何よりです。

  2. 匿名 より:

    よくまとめられていて助かりました

  1. 2020年11月6日

    […] 参考: systemdによる自動起動 | そう備忘録 […]

  2. 2021年2月18日

    […] Raspberry Pi で systemd を使ってプログラムを自動実行する – Qiitaラズパイのプログラムを、起動時や定刻に自動実行したい。 cronとかもあるが比較的新しくてイケてるらしいので、systemdとやらを使ってみようと思う。 脱コピペの思いで唸りながら理解したので、同じく脱コピペしたい初心者の同志に向け…qiita.com systemdによる自動起動 | そう備忘録systemdによる自動起動について調べた時の備忘録。www.souichi.club […]

  3. 2021年3月4日
  4. 2021年3月24日

    […] この他にも多くのパラメータが有ります。”systemdによる自動起動“ に各パラメータの説明が有ります参照下さい。 […]

  5. 2022年10月8日

    […] […]

質問やコメントや励ましの言葉などを残す

名前、メール、サイト欄は任意です。
またメールアドレスは公開されません。