execstartpre和execstartpost分别在主服务启动前、启动成功后执行一次,用于初始化检查与启动后通知;前者失败则服务启动中止,后者失败不影响服务状态。

ExecStartPre 和 ExecStartPost 是 systemd 服务单元(.service)中 [Service] 段的关键指令,分别用于在主服务进程启动前、启动成功后执行指定命令。它们不参与服务生命周期管理(如重启、停止),仅按顺序触发一次,适合做初始化检查、环境准备或启动后审计记录。
ExecStartPre:前置校验与初始化
该指令在 ExecStart 执行前运行,若任一 ExecStartPre 命令退出码非 0,整个服务启动失败,不会继续执行主进程。
- 支持多次定义,按出现顺序依次执行
- 可使用
%i、%n等 systemd 替换符(如%n表示完整 unit 名) - 常用场景包括:配置文件语法检查、目录创建、权限设置、端口占用检测
例如 Nginx 服务中常见写法:
[Service] ExecStartPre=/usr/sbin/nginx -t -c /etc/nginx/nginx.conf ExecStartPre=/bin/mkdir -p /var/run/nginx ExecStartPre=/bin/chown nginx:nginx /var/run/nginx
ExecStartPost:启动后审计与通知
该指令在 ExecStart 成功启动主进程(即进程已 fork 或进入 ready 状态,取决于 Type= 设置)后立即执行。它不阻塞服务状态切换,即使失败也不影响服务“active (running)”状态。
- 适合记录日志、上报启动事件、更新监控标记、发送 webhook 通知
- 不能依赖主进程的 PID 文件是否已写入(因执行时机早于 PIDFile 写入完成),如需 PID,建议用
$MAINPID变量(systemd 保证此时已知) - 注意:若
Type=notify,则ExecStartPost在收到 notify 信号后才执行
例如 Prometheus 启动后打点:
[Service] Type=simple ExecStart=/usr/local/bin/prometheus --config.file=/etc/prometheus.yml ExecStartPost=/bin/sh -c 'echo "$(date): prometheus started as $MAINPID" >> /var/log/prometheus/startup.log'
关键注意事项
- 所有 Exec* 指令默认在服务用户上下文中执行(由
User=和Group=控制),如需 root 权限需显式配置或改用PermissionsStartOnly=true -
PermissionsStartOnly=true时,仅ExecStartPre和ExecStart以 root 运行,其余如ExecStartPost降权到服务用户 - 命令路径必须绝对(如
/bin/sh,不可写sh),否则 systemd 无法解析 - 修改配置后必须运行
systemctl daemon-reload才生效











