【问题标题】:Recommended file format (YAML? JSON? Other?)推荐的文件格式(YAML?JSON?其他?)
【发布时间】:2013-08-20 12:19:51
【问题描述】:

在我开始之前,我应该声明我是 YAML 和 JSON 的新手,所以格式化规则不是那么清楚。

我正在尝试编写一个 Perl 脚本(Perl,因为我知道它存在于我们所有的服务器上。)它将为各种主机更新几个与网络相关的设置。我的偏好是将所有设置放在一个文件中,并根据运行脚本的主机更新配置。

我查看了 YAML,但由于无法执行以下操作,我有点犹豫:

host:
  hostname: first
    interface: eth0
      oldip: 1.2.3.4
      newip: 2.3.4.5
      oldgw: 1.2.3.1
      newgw: 2.3.4.1
    interface: eth1
      oldip: 1.2.3.4
      newip: 2.3.4.5
      oldgw: 1.2.3.1
      newgw: 2.3.4.1

host:
  hostname: second
    interface: eth0
      oldip: 1.2.3.4
      newip: 2.3.4.5
      oldgw: 1.2.3.1
      newgw: 2.3.4.1
    interface: eth1
      oldip: 1.2.3.4
      newip: 2.3.4.5
      oldgw: 1.2.3.1
      newgw: 2.3.4.1

也就是说,我已将其插入 YAML 验证器,但它失败了。

我发现,对于 YAML,我可以做到以下几点:

host: "first"
interface1:
  name: eth0
  oldip: 1.2.3.4
  newip: 2.3.4.5
  oldgw: 1.2.3.1
  newgw: 2.3.4.1
interface2:
  name: eth1
  oldip: 1.2.3.4
  newip: 2.3.4.5
  oldgw: 1.2.3.1
  newgw: 2.3.4.1

不过,这不太理想,因为它使得在一个文件中拥有多个主机是不可能的。我这样做是基于这样一个事实,即我在尝试此操作时一直从我使用的在线验证器中收到错误。

我研究过使用 JSON,但我也不知道所有的规则。我知道以下方法不起作用:

{
    "host": "first",
    "interface1": {
        "newip": "2.3.4.5",
        "oldip": "1.2.3.4",
        "oldgw": "1.2.3.1",
        "name": "eth0",
        "newgw": "2.3.4.1"
    },
    "interface2": {
        "newip": "2.3.4.5",
        "oldip": "1.2.3.4",
        "oldgw": "1.2.3.1",
        "name": "eth1",
        "newgw": "2.3.4.1"
    }
}

{
    "host": "second",
    "interface1": {
        "newip": "2.3.4.5",
        "oldip": "1.2.3.4",
        "oldgw": "1.2.3.1",
        "name": "eth0",
        "newgw": "2.3.4.1"
    },
    "interface2": {
        "newip": "2.3.4.5",
        "oldip": "1.2.3.4",
        "oldgw": "1.2.3.1",
        "name": "eth1",
        "newgw": "2.3.4.1"
    }
}

是否有一种格式可以让我将所有主机及其信息存储在一个可以解析的文件中?

如果 YAML 或 JSON 都适合,我做错了什么?

【问题讨论】:

  • 人类编写正确的 YAML 和 JSON 比阅读它更难。您应该在 Perl 中构建您的初始数据结构并使用 Perl 将其写入文件,至少一开始是这样。然后,如果你有勇气,你可以手动对文件进行一些小改动。

标签: json perl yaml


【解决方案1】:

不关心格式。填充一个数据结构,让JSONYAML 为您完成繁琐的工作。如果您要自己生成和解析文件,那么使用 JSON 或 YAML 几乎没有任何优势。

【讨论】:

    【解决方案2】:

    host 的 YAML 问题与 interface 最初的问题相同:您试图将子键与包含它们的键置于同一级别。

    host:
      name: first
      interface1:
        name: eth0
        oldip: 1.2.3.4
        newip: 2.3.4.5
        oldgw: 1.2.3.1
        newgw: 2.3.4.1
      interface2:
        name: eth1
        oldip: 1.2.3.4
        newip: 2.3.4.5
        oldgw: 1.2.3.1
        newgw: 2.3.4.1
    

    应该可以,尽管这仍然不能满足您对多个主机的需求。为此(为了更好地处理多个接口),您应该使用列表:

    host:
      - name: first_host
        interface:
          - name: eth0
            oldip: 1.2.3.4
            newip: 2.3.4.5
            oldgw: 1.2.3.1
            newgw: 2.3.4.1
          - name: eth1
            oldip: 1.2.3.4
            newip: 2.3.4.5
            oldgw: 1.2.3.1
            newgw: 2.3.4.1
      - name: second_host
        interface:
        - ...
    

    当被 Perl 读入时,这将为您提供结构:

    {
      "host": [
        {
          "interface": [
            {
              "newip": "2.3.4.5", 
              "oldip": "1.2.3.4", 
              "oldgw": "1.2.3.1", 
              "name": "eth0", 
              "newgw": "2.3.4.1"
            }, 
            {
              "newip": "2.3.4.5", 
              "oldip": "1.2.3.4", 
              "oldgw": "1.2.3.1", 
              "name": "eth1", 
              "newgw": "2.3.4.1"
            }
          ], 
          "name": "first_host"
        }
      ]
    }
    

    就 JSON 而言,它是 YAML 的一个子集。就个人而言,我更喜欢使用完整的 YAML 规范,但 JSON 提供了与非 Perl 语言的更多互操作性。

    【讨论】:

    • 每一种现代语言都支持 YAML,(您可能需要一个外部库,但仍然......)。让我知道是否有异常。
    • @KarolyHorvath - 公平点。我并没有考虑那么多语言,因为单个程序比 YAML 支持更可能包含 JSON 支持,尽管 Perl 程序似乎比其他语言的程序更可能包含 YAML 支持。但我措辞不好。
    • 我明白了。那么您指出的列表是 YAML 的一部分还是只是看起来相似?我确实将它插入到 YAML 验证器中并检查了它,所以我猜它只是 YAML 的另一个特性。
    • @theillien - 列表(官方称为“序列”)是 YAML 的一部分,是的。您可以在 yaml.org/spec/1.2/spec.html#id2759963 的 YAML 1.2 规范中找到它们的示例
    • @DaveSherohman 非常感谢。我认为这些信息会有很大帮助。
    【解决方案3】:

    确切的格式并不重要:YAML 和 JSON 都可以。实际上,我会建议保持这个特定的部分是可插拔的。

    YAML 的问题在于数据结构必须有意义,例如:

    - host:
        hostname: first
        interfaces:
          eth0:
            oldip: 1.2.3.4
            newip: 2.3.4.5
            oldgw: 1.2.3.1
            newgw: 2.3.4.1
          eth1:
            oldip: 1.2.3.4
            newip: 2.3.4.5
            oldgw: 1.2.3.1
            newgw: 2.3.4.1
    - host:
        hostname: second
        interfaces:
          ...
    

    或者如果必须订购接口:

    - host:
        hostname: first
        interfaces:
          -
            name: eth0
            oldip: 1.2.3.4
            newip: 2.3.4.5
            oldgw: 1.2.3.1
            newgw: 2.3.4.1
          -
            name: eth1
            oldip: 1.2.3.4
            newip: 2.3.4.5
            oldgw: 1.2.3.1
            newgw: 2.3.4.1
    

    如果手动编写 YAML 对您来说很乏味,只需编写一个小脚本为您生成它。

    请注意,列表必须通过- 之类的标记以某种方式引入。意图是不够的。

    【讨论】:

      【解决方案4】:

      我更喜欢 JSON 而不是 YAML。我最近构建了一个系统,它的“用户界面”(ha)基本上是一个巨大的配置文件;用户需要编辑该配置文件来控制系统;我对那个文件使用了 YAML。事实证明,YAML 有一些非常烦人的陷阱,使其不适合人类使用——例如,它对空格非常挑剔。

      此外,它一般不太熟悉:我猜任何有编程经验的人都接触过 JSON,并且理解它。但 YAML 更小众。

      如果您不使用 YAML 的高级功能(例如定义变量然后稍后引用它们的能力),我建议您改用 JSON。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-04-17
        • 2014-07-06
        • 2011-07-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-05-07
        相关资源
        最近更新 更多