返回 Bug 清单
BUG-0207project-08已修复deploy-config

systemd EnvironmentFile 不剥行内注释,且 CRLF 会带入 \r —— 配置静默失效

发现:2026-09-30验证:2026-10-31置信度:98%

症状

某守护功能(OmniCert 的 auto-renew)从未启动过。配置项 OMNICERT_ENABLE_AUTO_RENEW=true 看起来已开启,但应用读到后判断『未启用』。锁文件 auto-renew.lock 从未生成。

根因

两处叠加: ① 该行有【行内注释】:OMNICERT_ENABLE_AUTO_RENEW=true # Linux 生产开… systemd 的 EnvironmentFile 是【逐字读取】的,只有【行首】的 # 才是注释; 于是值变成 'true # Linux 生产开…' ⇒ 应用 .lower() != 'true' ⇒ 跳过。 ② 该文件是 CRLF 行尾,值尾部还带 \r。 注意:shell 的 `source` 会剥注释,所以『在 shell 里试是好的』,正是这一点让人误以为配置正确。

修复方案

1) 赋值行的行内注释一律移到独立行; 2) /etc/default/* 等 EnvironmentFile 统一用 LF(提交前用 check-file-encoding 类脚本把关); 3) 验证方式必须与运行时一致:用 systemctl show <svc> -p Environment 看 systemd 【实际解析出的值】,而不是在 shell 里 source; 4) 关键开关要有『生效证据』(如启动日志或锁文件),不能只看配置文本。

检测命令

grep -nE '^[A-Za-z_][A-Za-z0-9_]*=.*#' /etc/default/*; file /etc/default/* | grep CRLF

修复命令

python3 - <<'EOF'
import re
p='/etc/default/<svc>'
out=[]
for ln in open(p,encoding='utf-8').read().split('\n'):
    ln=ln.rstrip('\r')
    m=re.match(r'^([A-Za-z_][A-Za-z0-9_]*)=(.*?)(\s+#.*)$', ln)
    if m: out += ['%s=%s' % (m.group(1), m.group(2).strip()), m.group(3).strip()]
    else: out.append(ln)
open(p,'w',encoding='utf-8').write('\n'.join(out))
EOF
systemctl daemon-reload && systemctl restart <svc>

错误签名

应用日志: [auto-renew] skipped: OMNICERT_ENABLE_AUTO_RENEW not enabled;而配置文件里明明写着 =true

技术信息

来源项目

project-08

标签

systemd, environment-file, crlf, inline-comment, silent-failure