如何使用Ansible/jq递归查找包含根挂载点/的顶层块设备名
解决方案
方案1:使用jq命令直接处理(简单高效)
直接修改shell中的jq语句,利用递归遍历匹配根挂载点对应的顶层磁盘:
lsblk -oMOUNTPOINT,NAME --json | jq -r '.blockdevices[] | select(.. | .mountpoint? == "/") | .name'
参数说明
-r:输出原始字符串,自动去掉结果的双引号..:jq的递归遍历运算符,会遍历当前块设备下所有层级的子节点.mountpoint?:安全取值,不存在mountpoint字段的节点不会抛出错误select:只要当前顶层块设备的任意子节点存在mountpoint="/",就会被选中,最终输出对应的顶层磁盘名sda
对应playbook修改示例
- hosts: localhost tasks: - name: 直接查询根分区对应顶层磁盘 shell: lsblk -oMOUNTPOINT,NAME --json | jq -r '.blockdevices[] | select(.. | .mountpoint? == "/") | .name' register: root_disk - debug: msg: "{{ root_disk.stdout }}"
方案2:Ansible原生json_query实现(无需安装额外依赖)
利用JMESPath的递归下降语法,不需要额外安装jq,完全用Ansible自带功能实现:
- hosts: localhost tasks: - name: 获取块设备原始JSON信息 shell: lsblk -oMOUNTPOINT,NAME --json register: lsblk_output - name: 解析得到根分区对应顶层磁盘名 debug: msg: "{{ (lsblk_output.stdout | from_json) | json_query('blockdevices[?..mountpoint == `/`].name | [0]') }}"
查询逻辑说明
blockdevices[]:遍历所有顶层块设备[?..mountpoint ==/]:过滤规则:递归遍历当前块设备的所有子节点,存在mountpoint="/"的设备就保留当前顶层块设备.name:取符合条件的顶层设备的名称| [0]:取第一个匹配结果,根分区全局唯一,避免返回列表格式
两种方案执行后都会直接得到预期结果sda。
内容的提问来源于stack exchange,提问作者hago
相关产品推荐
相关产品推荐

