首页 > 解决方案 > 如何在 Ansible 中处理可以是字符串或列表的输出

问题描述

您好,我遇到了以下问题。基本上,我使用 PS 命令在 AD 上运行查询以获取 OU 列表。然后我想将我的变量与该列表进行比较。这是 PS 命令:

- name: PS - Pull SITE Sub OUs from AD for specific application 
  win_command: powershell - 
  args:
    stdin: "Get-ADOrganizationalUnit -LDAPFilter '(name=*)' -SearchScope 1  -SearchBase 'OU=SITES,DC=xxx,DC=int' -Server domain.int | select-object name | ConvertTo-Json"
  become: yes
  register: ou_site_out

仅存在单个 OU 时的输出: changed: [host] => {"changed": true, "cmd": "powershell -", "delta": "0:00:00.913282", "end": "2020-02 -13 04:04:26.289368”,“rc”:0,“start”:“2020-02-13 04:04:25.376086”,“stderr”:“”,“stderr_lines”:[],“stdout”: "{\r\n \"name\": \"OU1\"\r\n}\r\n", "stdout_lines": ["{", " \"name\": \"OU1\"" , "}"]}

存在多个OU时输出:

更改:[主机] => {“更改”:true,“cmd”:“powershell -”,“delta”:“0:00:00.875002”,“end”:“2020-02-13 04:25:49.409360 ", "rc": 0, "start": "2020-02-13 04:25:48.534358", "stderr": "", "stderr_lines": [], "stdout": "[\r\n { \r\n \"名称\": \"OU1\"\r\n },\r\n {\r\n \"名称\": \"OU2\"\r\n },\r\ n {\r\n \"名称\": \"OU3\"\r\n }]"

然后我从标准输出设置事实如下:

- name: Set list of  OUs as facts
   set_fact:
      ou_site_list: "{{ ou_site_out.stdout | from_json }}"

问题从这里开始。如果 ou_site_out 仅包含单个项目(仅存在 1 个 OU),则 ou_site_list 将返回字符串

TASK [debug] *******************************************************************
ok: [host] => {
    "ou_site_list": {
        "name": "OU1"

但如果有多个 OU,我会得到列表:

TASK [debug] *******************************************************************
ok: [host] => {
    "ou_site_list": [
        {
            "name": "OU1"
        },
        {
            "name": "OU2"
        },
        {
            "name": "OU3"}]

如果我不知道它是否是字符串列表,我该如何处理 ou_site_list ?

谢谢你的帮助

标签: stringlistansible

解决方案


根据您提供的示例,您可以通过查看输出的前导字符来知道:如果是[,则list,否则需要将其重新打包为list. type_debug过滤器可能是解决该问题的更便携的方法:

- set_fact:
    ou_site_list: ["a","b"]
  # then you can comment that one and uncomment this one
  # to see how it behaves in each case:
  # ou_site_list: "alpha"
- set_fact:
    ou_site_type: '{{ ou_site_list | type_debug }}'
- debug:
    msg: it's a list
  when: ou_site_type == 'list'
- debug:
    msg: it is not a list, and needs to be wrapped in one
  when: ou_site_type != 'list'
  # it's type is 'AnsibleUnicode' but for your purposes
  # just "not a list" is probably good enough

推荐阅读