关键是在无人值守apt升级中无条件保留已修改的配置文件,首选方式是创建/etc/apt/apt.conf.d/99force-confold并写入Dpkg::Options {"--force-confold"; "--force-confdef"};,确保所有apt操作默认生效。

在无人值守的 apt 升级中保留你精心调校过的生产配置(比如 /etc/ssh/sshd_config、/etc/nginx/nginx.conf 等),关键不是“跳过提示”,而是让 dpkg 明确知道:遇到冲突配置文件时,无条件保留当前已修改的版本。核心就是用 --force-confold,但必须配合正确的调用方式和上下文。
为什么只加 -o Dpkg::Options::="--force-confold" 不够
单独写 apt-get -o Dpkg::Options::="--force-confold" upgrade 很容易失效,原因有三:
- apt-get 在内部可能多次调用 dpkg,而该选项只作用于当前这次调用,不保证覆盖全部场景
- 某些包安装流程(如触发 maintainer scripts)可能绕过该设置
- 如果系统中已有
/etc/apt/apt.conf.d/下的全局配置覆盖了你的临时选项,也会被忽略
真正可靠的三种落地方式
按推荐顺序排列,兼顾稳定性与可维护性:
-
首选:全局配置文件(最稳妥)
创建/etc/apt/apt.conf.d/99force-confold,内容只有一行:Dpkg::Options {"--force-confold"; "--force-confdef"};
这样所有后续的apt和apt-get操作都会默认生效,无需每次重复指定 -
脚本内显式组合(最清晰)
在你的自动化升级脚本中,完整写出两个关键选项:sudo DEBIAN_FRONTEND=noninteractive apt-get -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" upgradeDEBIAN_FRONTEND=noninteractive是必须的,它关闭所有交互式前端(包括 debconf 提示),和 dpkg 选项协同才完整 -
Ansible 等工具中使用 dpkg_options 参数(运维友好)
在 apt 模块中直接传参:dpkg_options: "force-confold,force-confdef"
注意这里不用加--前缀,也不用引号包裹单个值;多个选项用英文逗号分隔即可
需要避开的典型误区
这些做法看似省事,实际风险高或无效:
- 只用
--force-confold而不配--force-confdef:当遇到“新包提供配置文件,但本地无旧版”这类情况时,仍可能卡住——--force-confdef表示“对没冲突的按默认行为处理”,是安全兜底 - 误用
--force-yes或--allow-unauthenticated:它们解决的是签名验证或依赖冲突问题,完全不干预配置文件逻辑 - 修改
/etc/dpkg/dpkg.cfg并添加force-confold:该文件控制的是直接调用dpkg -i的行为,对 apt-get 这类高层命令影响有限,且易被其他工具覆盖
验证是否生效的小技巧
升级前可快速模拟一次,观察是否会跳过配置提示:
- 先备份一个被监控的配置文件,例如:
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.pre-test - 手动触发一次带 force 选项的 upgrade:
sudo DEBIAN_FRONTEND=noninteractive apt-get -s -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" upgrade | grep -E "(sshd|config|Conf)" - 若输出中没有
configuration file相关的交互提示行,且显示类似installing new version...或keeping old config,即表示策略已就绪


















