Ansible:regex_search 过滤器比较以及如何调试 when 子句

lam*_*ier 3 ansible

今天我花了一些时间尝试编写一些 Ansible 脚本,以便仅在相关命令输出中不存在相应行的情况下运行命令。经过一番尝试和错误后,我得到了一些对我有用的东西,但我不清楚为什么我与空字符串的初始比较不起作用。

这是一个演示我的问题的剧本:

- name: test
  hosts: localhost
  tasks:
  - shell: "cat /tmp/cmdoutput"
    register: cmdoutput

  - debug: var=filtered_output
    vars:
      filtered_output: "{{ cmdoutput.stdout | regex_search(item) }}"
    with_items:
      - "aa .* xx"
      - "bb .* yy"

  - debug: msg="do action that inserts {{ item }}"
    with_items:
      - "aa .* xx"
      - "bb .* yy"
    when: cmdoutput.stdout | regex_search(item) == ""

  - debug: msg="do action that inserts {{ item }}"
    with_items:
      - "aa .* xx"
      - "bb .* yy"
    when: not cmdoutput.stdout | regex_search(item)
Run Code Online (Sandbox Code Playgroud)
cat /tmp/cmdoutput
aa b c d xx
aa f g h yy
bb i j k xx
Run Code Online (Sandbox Code Playgroud)

这会产生以下输出:

$ ansible-playbook test.yml 
 [WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'


PLAY [test] **********************************************************************************************************************

TASK [Gathering Facts] ***********************************************************************************************************
ok: [localhost]

TASK [shell] *********************************************************************************************************************
changed: [localhost]

TASK [debug] *********************************************************************************************************************
ok: [localhost] => (item=None) => {
    "filtered_output": "aa b c d xx"
}
ok: [localhost] => (item=None) => {
    "filtered_output": ""
}

TASK [debug] *********************************************************************************************************************
skipping: [localhost] => (item=None) 
skipping: [localhost] => (item=None) 

TASK [debug] *********************************************************************************************************************
skipping: [localhost] => (item=None) 
ok: [localhost] => (item=None) => {
    "msg": "do action that inserts bb .* yy"
}

PLAY RECAP ***********************************************************************************************************************
localhost                  : ok=4    changed=1    unreachable=0    failed=0   
Run Code Online (Sandbox Code Playgroud)

ie "filtered_output": "",但是当比较不匹配时出现以下情况。

所以我的问题是:

  • 为什么当条件匹配时第二次调试不""
  • regex_search 的输出是什么类型的对象?- 字符串、数组还是其他东西?
  • 有没有,或者我在哪里可以找到有关过滤器的更多信息regex_search?-(此时 AFAICT)它不在jinja doco中,仅作为简短示例出现在官方文档的过滤器部分中

我的 Ansible 版本:2.5.1

谢谢

Vla*_*tka 5

问:为什么当条件匹配“”时第二次调试不成功?

\n

A:当没有正则表达式匹配的NoneType类型的对象时,返回。该类型没有长度。而不是测试空字符串(题外话请参阅Ansible Lint: Don\xe2\x80\x99t 与空字符串比较

\n
    when: cmdoutput.stdout|regex_search(item) == ""\n
Run Code Online (Sandbox Code Playgroud)\n

使用(你的例子中已经有了它)

\n
    when: not cmdoutput.stdout|regex_search(item)\n
Run Code Online (Sandbox Code Playgroud)\n

None和空字符串的计算结果均为False 非空字符串的计算结果为True

\n
\n \n

问:“如何轻松查看这个 NoneType 对象?”

\n

答:使用过滤器type_debug。例如,如果搜索成功

\n
    - debug:\n        msg: "{{ cmdoutput.stdout|regex_search(\'a\') }}"\n      vars:\n        cmdoutput:\n          stdout: abc\n
Run Code Online (Sandbox Code Playgroud)\n

结果是一个字符串

\n
  msg: a\n
Run Code Online (Sandbox Code Playgroud)\n

可以看到结果的类型

\n
    - debug:\n        msg: "{{ cmdoutput.stdout|regex_search(\'a\')|type_debug }}"\n      vars:\n        cmdoutput:\n          stdout: abc\n
Run Code Online (Sandbox Code Playgroud)\n

给出

\n
  msg: str\n
Run Code Online (Sandbox Code Playgroud)\n

如果搜索失败,结果为None

\n
    - debug:\n        msg: "{{ cmdoutput.stdout|regex_search(\'x\') }}"\n      vars:\n        cmdoutput:\n          stdout: abc\n
Run Code Online (Sandbox Code Playgroud)\n
  msg: \'\'\n
Run Code Online (Sandbox Code Playgroud)\n
    - debug:\n        msg: "{{ cmdoutput.stdout|regex_search(\'x\')|type_debug }}"\n      vars:\n        cmdoutput:\n          stdout: abc\n
Run Code Online (Sandbox Code Playgroud)\n
  msg: NoneType\n
Run Code Online (Sandbox Code Playgroud)\n
\n