修改systemd服务文件后daemon-reload无效,根本原因是systemd加载了/run或/var/run下的缓存副本或drop-in覆盖;需用systemctl cat确认实际加载路径,检查drop-in、Alias、Type配置,并用systemd-analyze verify验证语法。
修改 systemd 服务文件后 systemctl daemon-reload 没用?
常见现象是改了 /etc/systemd/system/myapp.service,执行了 systemctl daemon-reload,但 systemctl show myapp 或重启服务后配置项(比如 Environment=、ExecStart=)仍是旧值。
根本原因通常是:systemd 加载的是缓存副本,而非你正在编辑的文件。它会优先读取 /run/systemd/system/ 或 /var/run/systemd/system/ 下的生成式单元文件(尤其当服务由 generator 生成或被 drop-in 覆盖时)。
- 先运行
systemctl cat myapp,确认实际加载的是哪个路径下的文件(注意输出顶部的 “Loaded:” 行) - 如果显示加载的是
/run/systemd/system/myapp.service,说明有 generator 或临时覆盖,直接编辑/etc/systemd/system/下的文件无效 - 检查是否存在 drop-in 目录:
/etc/systemd/system/myapp.service.d/*.conf,它们的优先级高于主文件,会覆盖同名字段 - 确认没在
.service文件里误写Alias=或WantedBy=导致 unit 名称被重定向
systemctl restart 后进程环境变量还是旧的?
systemd 不会把已启动进程的环境变量“热更新”进去,restart 是杀掉旧进程、用新配置拉起新进程 —— 但如果你用的是 fork+daemonize 模式(比如传统 SysV 风格的守护进程),主进程可能立刻退出,子进程脱离 systemd 管控,后续就不再受其环境或资源限制约束。
- 检查服务是否设置了
Type=forking,且正确声明了PIDFile=;否则 systemd 无法跟踪真正的工作进程 - 更推荐改用
Type=simple(默认)或Type=notify,避免 fork 分离 - 验证环境变量是否生效:用
systemctl show --property=Environment myapp查看 systemd 解析后的值,再用cat /proc/$(pidof myapp)/environ | tr '\0' '\n'看实际进程看到的环境 - 注意
EnvironmentFile=中的变量不会自动导出到 shell 子进程,需显式Environment=FOO=$FOO才能透传
配置改了但日志里看不到变化?
日志内容不更新,往往不是配置没生效,而是 journal 没刷新、或服务根本没按预期重载配置 —— 尤其对那些支持运行时重载(如 nginx -s reload、redis-cli CONFIG REWRITE)但未集成到 systemd 的服务。