journalctl 是 systemd 启动过程的唯一可信证据源;需结合 systemctl status -l --no-pager 查 loaded、process、main pid 三行,并用 journalctl -u service -b -p err..emerg 定位失败前最后一秒错误。

journalctl 不是查日志的“辅助命令”,而是 systemd 启动过程的唯一可信证据源。当服务起不来,别急着改配置或重启,先让 journalctl 把真实执行链路还原出来。
看 status 时重点抓三行
运行 systemctl status your-service.service -l --no-pager,别只扫一眼红色 failed:
-
Loaded 行:确认路径是否真实存在,比如显示
loaded (/etc/systemd/system/myapp.service; enabled),就去检查这个文件是否存在、是否被覆盖(可用systemctl cat myapp.service验证) -
Process 行:留意
status=203/EXEC这类编码——它表示 systemd 根本没跑起来 ExecStart 命令,常见于脚本路径写错、缺少执行权限、或解释器(如#!/bin/bash)不可用 -
Main PID 行:若显示
Main PID: 12345 (code=exited, status=1/FAILURE),说明进程启动了但立刻退出,这时必须查 journalctl;若显示Main PID: unknown或为空,代表连进程都没 fork 出来,问题在更前置环节
用 journalctl 锁定“失败前最后一秒”
空日志不是没日志,是没走到日志写入阶段。优先执行:
-
journalctl -u your-service.service -b --no-pager:只查本次开机后的记录,排除历史干扰 -
journalctl -u your-service.service --since "2026-07-07 08:00" --no-pager:结合当前时间精确切片,避免滚动太多无关内容 -
journalctl -u your-service.service -p err..emerg --no-pager:只提取错误及以上级别,快速聚焦关键报错,比如Permission denied、No such file or directory、Failed at step EXEC spawning
绕过 systemd 直接验证启动命令
如果 journalctl 和 status 都没给出明确路径错误,就手动模拟 systemd 的执行环境:
- 用
systemctl show your-service.service | grep -E "(ExecStart|User|Group|WorkingDirectory)"提取实际生效的字段 - 切换到对应用户:
sudo -u your-user -s,再 cd 到 WorkingDirectory,最后完整复制 ExecStart 命令执行一次(注意去掉%i、%n等占位符) - 观察是否报 bash 解析错误、找不到二进制、权限拒绝,或 stdout/stderr 被重定向导致看不到输出
检查 unit 文件语义是否自洽
很多失败源于 Type 和实际行为不匹配:
- Type=oneshot 却没设
RemainAfterExit=yes,服务启动完立即标记为 inactive - Type=simple 但程序启动后后台化(如加
&),systemd 误判为主进程退出 - 用了
ExecStartPre检查依赖,但脚本 exit 非零却没加ConditionPathExists=等前置条件,导致失败不报具体原因











