Ansible无法将字符串从stdout_lines转换为字典 [英] Ansible unable to convert string to dictionary from the stdout_lines

查看:145
本文介绍了Ansible无法将字符串从stdout_lines转换为字典的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从字典中获取计数"值

I am trying to get the "count" value from the dictionary

"{\" _ id \:ObjectId(\" 5d3a1643c43c898d01a3c740 \),\" count \:2}"

"{ \"_id\" : ObjectId(\"5d3a1643c43c898d01a3c740\"), \"count\" : 2 }"

出现在ansible stdout_lines的最后一个元素上.

present at the last element of the ansible stdout_lines.

TASK [version_update : debug] ******************************************************************************************************************************************
ok: [192.168.27.125] => {
    "count_info.stdout": "MongoDB shell version v4.0.6\nconnecting to: mongodb://127.0.0.1:27017/configure-db?gssapiServiceName=mongodb\nImplicit session: session { \"id\" : UUID(\"4bfad3ba-981f-47de-86f9-a1fadbe28e12\") }\nMongoDB server version: 4.0.6\n{ \"_id\" : ObjectId(\"5d3a1643c43c898d01a3c740\"), \"count\" : 2 }"
}

TASK [version_update : debug] ******************************************************************************************************************************************
ok: [192.168.27.125] => {
    "count_info.stdout_lines": [
        "MongoDB shell version v4.0.6",
        "connecting to: mongodb://127.0.0.1:27017/configure-db?gssapiServiceName=mongodb",
        "Implicit session: session { \"id\" : UUID(\"4bfad3ba-981f-47de-86f9-a1fadbe28e12\") }",
        "MongoDB server version: 4.0.6",
        "{ \"_id\" : ObjectId(\"5d3a1643c43c898d01a3c740\"), \"count\" : 2 }"
    ]
}

我尝试了以下两种方法,但没有成功.

I tried the following two ways but not successful.

- debug:
    msg: "{{ (count_info.stdout_lines[-1] | from_json).count }}"

- name: count value
  debug:
    msg: "{{ count_info.stdout_lines[-1] | json_query('count') }}"

错误日志:

TASK [version_update : debug] ******************************************************************************************************************************************
fatal: [192.168.27.125]: FAILED! => {"msg": "the field 'args' has an invalid value ({u'msg': u'{{ (count_info.stdout_lines[-1] | from_json).count }}'}), and could not be converted to an dict.The error was: No JSON object could be decoded\n\nThe error appears to have been in '/home/admin/playbook-3/roles/version_update/tasks/version_update.yml': line 73, column 3, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n- debug:\n  ^ here\n"}
        to retry, use: --limit @/home/admin/playbook-3/version_update.retry

TASK [version_update : count value] ************************************************************************************************************************************
ok: [192.168.27.125] => {
    "msg": ""
}

推荐答案

尽管该元素具有字典的结构,但实际上是一个字符串,我无法使用to_jsonto_nice_json对其进行过滤以将其转换为一本字典.

although the element has the structure of a dictionary, its in fact a string, which i couldnt filter it with to_json or to_nice_json to convert it to a dictionary.

使用以下任务序列将获得您想要获取的值,不幸的是,我没有找到一种在一项任务中做到这一点的方法.逻辑如下:

using the below sequence of tasks will get the value you want to pick up, unfortunately i didnt find a way to do it in one task. the logic is as follows:

  1. 从列表中获取最后一个元素,并将字符串拆分为键值子字符串,并用,分隔.

解析此列表并找到包含关键字count的元素(如果您认为count也可能出现在其他行中,则可以在此处进行增强).然后使用正则表达式从中获取数值.

parse this list and find the element that contains the keyword count (you can enhance it here if you think the count may appear in other lines too). then with regex, get the numerical value out of it.

PB:

---
- hosts: localhost
  gather_facts: false
  vars:
    final_count_value: -1
    count_info:
      stdout_lines:
      - MongoDB shell version v4.0.6
      - 'connecting to: mongodb://127.0.0.1:27017/configure-db?gssapiServiceName=mongodb'
      - 'Implicit session: session { "id" : UUID("4bfad3ba-981f-47de-86f9-a1fadbe28e12")
        }'
      - 'MongoDB server version: 4.0.6'
      - '{ "_id" : ObjectId("5d3a1643c43c898d01a3c740"), "count" : 2 }'

  tasks:
    - name: prepare list var
      set_fact:
        temp_list: "{{ (count_info.stdout_lines | last).split(', ') | list }}"

    - name: find count
      set_fact: 
        final_count_value: "{{ item | regex_replace('\"count\" : ', '') | regex_replace(' }', '') }}"
      when: item is search('count')
      with_items:
      - "{{ temp_list }}"

    - name: print result
      debug:
        var: final_count_value

输出:

PLAY [localhost] *******************************************************************************************************************************************************************************************************

TASK [prepare list var] ************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [find count] ******************************************************************************************************************************************************************************************************
skipping: [localhost] => (item={ "_id" : ObjectId("5d3a1643c43c898d01a3c740")) 
ok: [localhost] => (item="count" : 2 })

TASK [print result] ****************************************************************************************************************************************************************************************************
ok: [localhost] => {
    "final_count_value": "2"
}

更新

要从结果中减去1,则应使用:

to subtract 1 from the result, you should use:

- name: find count and subtract 1
  set_fact: 
    final_count_value: "{{ item | regex_replace('\"count\" : ', '') | regex_replace(' }', '') | int - 1 }}"
  when: item is search('count')
  with_items:
  - "{{ temp_list }}"

希望有帮助!.

这篇关于Ansible无法将字符串从stdout_lines转换为字典的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆