やりたいこと
サーバーの再起動後やデプロイ後に、起動に失敗しているsystemdのユニットがないかをまとめて確認したい。
systemctl status [ユニット名]でユニットごとの詳細は確認できる。
ただし、どのユニットが失敗しているかわからない状態では、失敗したユニットだけを一覧表示する方法が必要になる。
systemctl –failed
systemctl --failedを実行すると、状態がfailedのユニットだけを一覧表示できる。
$ systemctl --failed
UNIT LOAD ACTIVE SUB DESCRIPTION
● myapp.service loaded failed failed My sample application
● mybatch.service loaded failed failed My batch job
Legend: LOAD → Reflects whether the unit definition was properly loaded.
ACTIVE → The high-level unit activation state, i.e. generalization of SUB.
SUB → The low-level unit activation state, values depend on unit type.
2 loaded units listed.
ACTIVE列がfailedのユニットが表示される。
失敗したユニットがない場合は0 loaded units listed.と表示される。
$ systemctl --failed
UNIT LOAD ACTIVE SUB DESCRIPTION
0 loaded units listed.
--failedは--state=failedの省略形である。
systemctl --helpにもShortcut for --state=failedと記載されている。
以下のコマンドはどれも同じ結果になる。
$ systemctl --failed
$ systemctl list-units --failed
$ systemctl list-units --state=failed
具体例
起動コマンドが成功しても失敗しているユニットを見つける
Type=simple(デフォルト)のサービスは、プロセスを起動した時点でsystemctl startが成功を返す。
起動直後にプロセスが異常終了した場合も、systemctl startの終了コードは0になる。
以下のユニットで確認する。
[Unit]
Description=My sample application
[Service]
ExecStart=/bin/sh -c 'echo "config not found" >&2; exit 1'
systemctl startの終了コードは0である。
$ sudo systemctl start myapp.service
$ echo $?
0
systemctl --failedを実行すると、myapp.serviceがfailedの状態で表示される。
$ systemctl --failed
UNIT LOAD ACTIVE SUB DESCRIPTION
● myapp.service loaded failed failed My sample application
...
失敗の原因はsystemctl statusで確認できる。
$ systemctl status myapp.service
× myapp.service - My sample application
Loaded: loaded (/etc/systemd/system/myapp.service; static)
Active: failed (Result: exit-code) since Sat 2026-11-14 06:03:40 UTC; 1s ago
Duration: 915us
Process: 133 ExecStart=/bin/sh -c echo "config not found" >&2; exit 1 (code=exited, status=1/FAILURE)
Main PID: 133 (code=exited, status=1/FAILURE)
CPU: 651us
Nov 14 06:03:40 c3c3ae659236 systemd[1]: Started myapp.service - My sample application.
Nov 14 06:03:40 c3c3ae659236 sh[133]: config not found
Nov 14 06:03:40 c3c3ae659236 systemd[1]: myapp.service: Main process exited, code=exited, status=1/FAILURE
Nov 14 06:03:40 c3c3ae659236 systemd[1]: myapp.service: Failed with result 'exit-code'.
参考: journalctlでsystemdのサービスのログを見る
ユニットの種類で絞り込む
--typeオプションと組み合わせると、ユニットの種類で絞り込める。
以下はサービスだけを表示する例。
$ systemctl --failed --type=service
タイマーだけを表示する場合は--type=timerを指定する。
スクリプトで扱いやすい形式で出力する
--plainで先頭の●を、--no-legendでヘッダーと凡例を省略できる。
失敗したユニット名をスクリプトで処理する場合に便利である。
$ systemctl --failed --plain --no-legend
myapp.service loaded failed failed My sample application
mybatch.service loaded failed failed My batch job
ユニット名だけを取り出す例。
$ systemctl --failed --plain --no-legend | awk '{print $1}'
myapp.service
mybatch.service
失敗したユニットの有無にかかわらず、systemctl --failedの終了コードは常に0である。
スクリプトで失敗を判定したい場合は、後述のsystemctl is-failedやsystemctl is-system-runningを使う。
関連するコマンド
systemctl is-failed
systemctl is-failedはユニット名を指定して、そのユニットがfailedかどうかを判定する。
failedの場合は終了コード0、それ以外の場合は0以外を返す。
$ systemctl is-failed myapp.service
failed
$ echo $?
0
$ systemctl is-failed systemd-journald.service
active
$ echo $?
1
systemctl is-system-running
failedのユニットが1つでもあると、systemctl is-system-runningはdegradedを返す。
終了コードも0以外になる。
$ systemctl is-system-running
degraded
$ echo $?
1
起動処理が完了していて失敗したユニットがない場合はrunningを返し、終了コードは0になる。
$ systemctl is-system-running
running
$ echo $?
0
起動処理中のstartingや停止処理中のstoppingでも、終了コードは0以外になる。
失敗したユニットの有無だけを判定したい場合は、終了コードではなく出力がdegradedかどうかで判定する。
if [ "$(systemctl is-system-running)" = "degraded" ]; then
systemctl --failed
fi
systemctl reset-failed
failedの状態はユニットの起動に再び成功するか、systemctl reset-failedを実行するまで残る。
原因を調査し終えたユニットを一覧から消すにはsystemctl reset-failedを使う。
ユニット名を指定すると、指定したユニットのfailed状態だけをリセットする。
$ sudo systemctl reset-failed mybatch.service
$ systemctl --failed
UNIT LOAD ACTIVE SUB DESCRIPTION
● myapp.service loaded failed failed My sample application
...
ユニット名を省略すると、すべてのユニットのfailed状態をリセットする。
$ sudo systemctl reset-failed
$ systemctl --failed
UNIT LOAD ACTIVE SUB DESCRIPTION
0 loaded units listed.
systemctl reset-failedはユニットの状態だけをリセットする。
ユニットファイルは削除されない。
動作確認した環境
Ubuntu 24.04のDockerコンテナでsystemdを起動して動作を確認した。
$ systemctl --version
systemd 255 (255.4-1ubuntu8.18)
