为什么stdout_lines [1,2]和[3,4]字符串而不是数组?

时间:2019-01-13 10:43:18

标签: ansible

shell command在标准输出上每行输出一个数组:[1,2]然后[3,4]。我想将数组的每个元素用作模块的参数,并决定在loopstdout_lines。但是,item.0item.1包含字符串的第一个和第二个字符,而不是数组的第一个和第二个元素。

  • 为什么item是字符串而不是数组?
  • 获得我所需要的东西的最优雅的方式是什么?

这里是转载者,可以使用ansible 2.7.5帮助您理解问题。以下播放:

---
- name: test
  hosts: localhost
  become: false
  gather_facts: false

  tasks:
    - name: one array per line
      shell: |
        echo '[1,2]'
        echo '[3,4]'
      register: result

    - name: each item is an array
      debug:
        msg: "{{ item }}"
      loop: "{{ result.stdout_lines }}"

    - name: accessing the first element of an item
      debug:
        msg: "{{ item.0 }} => {{ item.1 }}"
      loop: "{{ result.stdout_lines }}"

实际输出为:

TASK [each item is an array] *****************************************************
ok: [localhost] => (item=[1, 2]) => {
    "msg": [
        1, 
        2
    ]
}
ok: [localhost] => (item=[3, 4]) => {
    "msg": [
        3, 
        4
    ]
}

TASK [accessing the first element of an item] ************************************
ok: [localhost] => (item=[1, 2]) => {
    "msg": "[ => 1"
}
ok: [localhost] => (item=[3, 4]) => {
    "msg": "[ => 3"
}

但我期望:

TASK [each item is an array] *****************************************************
ok: [localhost] => (item=[1, 2]) => {
    "msg": [
        1, 
        2
    ]
}
ok: [localhost] => (item=[3, 4]) => {
    "msg": [
        3, 
        4
    ]
}

TASK [accessing the first element of an item] ************************************
ok: [localhost] => (item=[1, 2]) => {
    "msg": "1 => 2"
}
ok: [localhost] => (item=[3, 4]) => {
    "msg": "3 => 4"
}

2 个答案:

答案 0 :(得分:0)

一种选择是将字符串列表转换为列表列表。

    - name: convert strings to lists
      set_fact:
        lists: "{{ lists }} + [ {{ item }} ]"
      loop: "{{ result.stdout_lines }}"

    - name: accessing the 1st and 2nd element of a list
      debug:
        msg: "{{ item.0 }} => {{ item.1 }}"
      loop: "{{ lists }}"

答案 1 :(得分:0)

与Pilou在#ansible-fr@irc.freenode.net上进行讨论之后,找到了一个简单的解决方案。

通过向另一个变量分配item的内容来触发jinja2评估就足够了。如果可能,它将从字符串转换为结构。请参阅使用以下解决方案更新的测试手册。

      debug:
        msg: "{{ array.0 }} => {{ array.1 }}"
      vars:
        array: "{{ item }}"
      loop: "{{ result.stdout_lines }}"

没有理由解释为什么在可能的情况下将stdout转换为结构,但没有解释stdout_lines中的元素。 shell模块是这样实现的。将来可能会改变。如果是这种情况,建议的解决方案将继续有效。只是没有必要。

---
- name: test
  hosts: localhost
  become: false
  gather_facts: false

  tasks:
    - name: one array per line
      shell: |
        echo '[1,2]'
        echo '[3,4]'
      register: result

    - name: each item is an array
      debug:
        msg: "{{ item }}"
      loop: "{{ result.stdout_lines }}"

    - name: accessing the first element of an item
      debug:
        msg: "{{ array.0 }} => {{ array.1 }}"
      vars:
        array: "{{ item }}"
      loop: "{{ result.stdout_lines }}"