首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用Ansible/jq/json递归地搜索包含感兴趣元素的列表字典?

如何使用Ansible/jq/json递归地搜索包含感兴趣元素的列表字典?
EN

Stack Overflow用户
提问于 2021-11-25 17:15:37
回答 2查看 186关注 0票数 0

我有一个Ansible剧本(版本2.9),它最初使用lsblk命令显示可用的块设备。剧本是

代码语言:javascript
复制
- hosts: localhost
  tasks:
  - name: define variable
    shell: lsblk -oMOUNTPOINT,NAME  --json
    register: lsblk_output
  - debug:
      msg: "{{ lsblk_output.stdout }}"

lsblk命令的输出为JSON格式,lsblk -oMOUNTPOINT,NAME -json是

代码语言:javascript
复制
ok: [localhost] => {
    "msg": {
        "blockdevices": [
            {
                "mountpoint": "/snap/core18/2246",
                "name": "loop0"
            },
            {
                "mountpoint": "/snap/core18/2253",
                "name": "loop1"
            },
            {
                "mountpoint": "/snap/core20/1169",
                "name": "loop2"
            },
            {
                "mountpoint": "/snap/lxd/21803",
                "name": "loop3"
            },
            {
                "mountpoint": "/snap/core20/1242",
                "name": "loop4"
            },
            {
                "mountpoint": "/snap/lxd/21835",
                "name": "loop5"
            },
            {
                "mountpoint": "/snap/snapd/14066",
                "name": "loop6"
            },
            {
                "mountpoint": "/snap/snapd/13640",
                "name": "loop7"
            },
            {
                "children": [
                    {
                        "mountpoint": "/boot/efi",
                        "name": "sda1"
                    },
                    {
                        "mountpoint": "/boot",
                        "name": "sda2"
                    },
                    {
                        "children": [
                            {
                                "children": [
                                    {
                                        "mountpoint": "/",
                                        "name": "ubuntu--vg-ubuntu--lv"
                                    },
                                    {
                                        "mountpoint": null,
                                        "name": "ubuntu--vg-clean"
                                    }
                                ],
                                "mountpoint": null,
                                "name": "ubuntu--vg-ubuntu--lv-real"
                            },
                            {
                                "children": [
                                    {
                                        "mountpoint": null,
                                        "name": "ubuntu--vg-clean"
                                    }
                                ],
                                "mountpoint": null,
                                "name": "ubuntu--vg-clean-cow"
                            }
                        ],
                        "mountpoint": null,
                        "name": "sda3"
                    }
                ],
                "mountpoint": null,
                "name": "sda"
            },
            {
                "children": [
                    {
                        "mountpoint": null,
                        "name": "datavg-datavol1"
                    }
                ],
                "mountpoint": null,
                "name": "sdb"
            }
        ]
    }
}

如果我将上面的shell命令修改为lsblk -oMOUNTPOINT,名称为-json区jq‘.json\jq '.blockdevices[]区选择(.mountpoint == null) \ .name’

输出是

代码语言:javascript
复制
TASK [debug] *************************************************************************************************************************************************************
ok: [localhost] => {
    "msg": "\"sda\"\n\"sdb\""
}

但是,基于驱动器包含“挂载点”:"/“这一事实,我只需要一个驱动器名。预期输出为sda。否则,我如何修改上述shell命令,以便执行递归搜索并获得所需的输出?

UPDATE我一直在扮演这个角色,

代码语言:javascript
复制
  - name: task22
    debug:
      msg: "{{ jsonym.blockdevices }}"
  - debug:
      msg: "{{ ((jsonym.blockdevices) | flatten) | json_query(query) | list }} "

    vars:
            query: "[].children.{na:jsonym.name, mp: [?mountpoint == '/boot'].name }"

输出是任务调试****************************************************************************************。

代码语言:javascript
复制
ok: [localhost] =>
  msg:
  - mp:
    - sda2
    na: null
  - mp: []
    na: null

仍然无法获得预期的产出。

EN

回答 2

Stack Overflow用户

发布于 2021-11-25 18:10:29

注册变量lsblk_output.stdout是包含JSON数据的字符串。您必须通过from_yaml (或from_json,任何您喜欢的)从字符串中阅读字典。然后接受属性块设备并选择挂载点。例如,给定数据

代码语言:javascript
复制
  lsblk_output:
    stdout:
      blockdevices:
      - children:
        - mountpoint: /
          name: nvme0n1p6
        - mountpoint: /export
          name: nvme0n1p7
        mountpoint: null
        name: nvme0n1
      - children:
        - mountpoint: /root2
          name: nvme0n2p6
        - mountpoint: /export2
          name: nvme0n2p7
        mountpoint: null
        name: nvme0n2

下面的查询给出了'/‘挂载点的名称

代码语言:javascript
复制
  - debug:
      msg: "{{ (lsblk_output.stdout|from_yaml).blockdevices|
               json_query(query)|
               flatten }}"
    vars:
      query: "[].*[?mountpoint == '/'].name"
代码语言:javascript
复制
  msg:
  - nvme0n1p6
票数 1
EN

Stack Overflow用户

发布于 2021-11-26 07:02:12

如果您使用gather_facts,您可以利用ansible_mounts事实而不是运行lsblk

下面这样的任务可以过滤出安装在/上的磁盘/分区。

代码语言:javascript
复制
    - name: show root disk
      debug:
        msg: "{{ ansible_mounts | json_query(query) | first }}"
      vars:
        query: "[?mount == '/'].device"

结果如下:

代码语言:javascript
复制
ok: [localhost] => {
    "msg": "/dev/sda1"
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70115064

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档