You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用ConfigParser写入含重复键的systemd-networkd配置文件

实现支持重复键的INI配置写入(适配systemd-networkd)

systemd-networkd的配置文件采用INI格式,但允许出现重复键(比如多个DNS=条目)。标准Python ConfigParser无法直接通过列表生成这类重复键——直接写入会把列表转换成字面量字符串,不符合要求。

我们希望能用这种直观的方式定义配置:

conf = ConfigParser()
conf.optionxform = str  # 保留键的大小写(systemd-networkd对大小写敏感)

conf["Match"] = {"Name": "eth0"}
conf["Network"] = {
    "DHCP": "no",
    "Address": "10.0.0.12/24",
    "Gateway": "10.0.0.1",
    "DNS": ["1.1.1.1", "8.8.8.8"],
}

优化后的实现方案

不需要依赖ast.literal_eval解析值,直接在写入阶段判断值的类型,更直接且避免潜在的解析错误:

from configparser import ConfigParser

class SystemdConfigParser(ConfigParser):
    def _write_section(self, fp, section_name, section_items, delimiter):
        # 写入section头
        fp.write(f"[{section_name}]\n")
        
        for key, value in section_items:
            # 保留ConfigParser原有的插值处理逻辑
            value = self._interpolation.before_write(self, section_name, key, value)
            
            if isinstance(value, list):
                # 列表类型:循环生成重复键条目
                for item in value:
                    item_str = delimiter + str(item).replace("\n", "\n\t") if (item is not None or not self._allow_no_value) else ""
                    fp.write(f"{key}{item_str}\n")
            else:
                # 普通值:按标准逻辑写入
                value_str = delimiter + str(value).replace("\n", "\n\t") if (value is not None or not self._allow_no_value) else ""
                fp.write(f"{key}{value_str}\n")
        
        # 每个section后添加空行分隔
        fp.write("\n")

使用示例

conf = SystemdConfigParser()
conf.optionxform = str

conf["Match"] = {"Name": "eth0"}
conf["Network"] = {
    "DHCP": "no",
    "Address": "10.0.0.12/24",
    "Gateway": "10.0.0.1",
    "DNS": ["1.1.1.1", "8.8.8.8"],
}

# 写入到配置文件
with open("/etc/systemd/network/eth0.network", "w") as f:
    conf.write(f)

生成的配置文件内容如下,完全符合systemd-networkd的要求:

[Match]
Name=eth0

[Network]
DHCP=no
Address=10.0.0.12/24
Gateway=10.0.0.1
DNS=1.1.1.1
DNS=8.8.8.8

对比原有实现的优势

  • 更可靠:直接检查值的类型,避免了ast.literal_eval可能带来的误判(比如值本身是类似列表的字符串"[1,2,3]"时,原代码会错误解析为列表)
  • 更简洁:去掉了不必要的异常捕获和解析步骤,逻辑更清晰
  • 兼容性好:完整保留了ConfigParser原有的插值处理逻辑,不影响其他功能

内容的提问来源于stack exchange,提问作者David White

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 22:59:50