You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Ansible results的stdout_lines中搜字符串并按when条件执行新Play

Ansible 从register结果的stdout_lines中匹配字符串并控制任务执行

当你用with_items执行任务并通过register捕获结果时,play.results是一个列表,每个元素对应一次with_items迭代的任务输出。原代码里的when条件写法无法正确检查stdout_lines中的内容,以下是正确的实现方式:

核心说明

play.results里的每个元素包含stdout(命令输出字符串)、stdout_lines(按行拆分的输出列表)、item(当前迭代的用户)等字段。我们需要借助Ansible过滤器来筛选符合条件的结果。

场景1:只要存在一个匹配结果就执行任务

如果需要任意一个用户的执行结果包含目标字符串时触发后续任务,可这样写:

- hosts: server-a
  become: yes
  gather_facts: false

  vars_files:
     - filename.yml
  vars:
    target_string: "root"  # 替换为你要搜索的目标字符串

  tasks:
    - shell: whoami
      with_items: "{{ users }}"
      become_user: "{{ item }}"
      register: play

    - debug:
        msg: "System {{ inventory_hostname }} 存在匹配目标字符串的执行结果"
      when: play.results | selectattr('stdout_lines', 'contains', target_string) | list | length > 0

这里用selectattr过滤器筛选出stdout_lines包含目标字符串的结果,转成列表后判断长度是否大于0,只要有一个匹配就触发任务。

场景2:所有结果都匹配才执行任务

如果需要所有用户的执行结果都包含目标字符串才触发任务,可使用rejectattr反向筛选:

- debug:
    msg: "System {{ inventory_hostname }} 所有执行结果都匹配目标字符串"
  when: play.results | rejectattr('stdout_lines', 'contains', target_string) | list | length == 0

rejectattr会找出不匹配的结果,若结果列表长度为0,说明所有迭代的输出都符合要求。

场景3:针对每个匹配结果单独执行任务

如果需要对每个匹配的用户结果单独处理,可以直接遍历过滤后的结果列表:

- debug:
    msg: "用户 {{ item.item }} 的执行结果包含目标字符串:{{ item.stdout }}"
  loop: "{{ play.results | selectattr('stdout_lines', 'contains', target_string) | list }}"

这样每个符合条件的结果都会独立触发一次debug任务,输出对应的用户和执行结果。

原代码的问题点

原代码中的when: play['results'] contains specific string写法错误:

  • contains过滤器用于检查字符串是否包含子串,或列表是否包含某个完整元素
  • play.results是任务结果的列表,直接使用会检查列表中是否存在等于specific string的元素,而非检查每个元素的stdout_lines内容

内容的提问来源于stack exchange,提问作者blue

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 16:45:44