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

如何在Ansible后续任务中仅提取register输出中的SUCCESSFUL值?

问题

想在Ansible后续任务里提取第一个任务register输出中的SUCCESSFUL字符串,但执行时出现错误,结果不符合预期。

原Playbook内容:

cat play1.yml
---
- hosts: all
  connection: local
  gather_facts: false

  tasks:
   - name: Parse result info
     shell: |
       cmd: |
       echo "Result output goes here. Some Exception number details : Exception from HRESULT" | grep "Exception from HRESULT"
       excep_status=`echo $?`
       if (( $excep_status == 0)) ; then
         echo "SUCCESSFUL"  # Exception present
       elif (( $excep_status == 1)) ; then
         echo "FAILED"
       fi
     register: ExcepStatus
     delegate_to: localhost

   - debug: msg="{{ExcepStatus.stdout}}"

   - name: echo ExcepStatus
     shell: |
       echo {{ ExcepStatus.stdout }}
     delegate_to: localhost

清单文件:

$ cat inv
localhost

执行报错结果:

$ ansible-playbook -i inv play1.yml
    PLAY [all] **************************************************************************************************************************************************

TASK [Parse result info] ************************************************************************************************************************************
changed: [localhost -> localhost]

TASK [debug] ************************************************************************************************************************************************

    ok: [localhost] => {
        "msg": "Result output goes here. Some Exception number details : Exception from HRESULT\nSUCCESSFUL"
    }

TASK [echo ExcepStatus] *************************************************************************************************************************************
fatal: [localhost -> localhost]: FAILED! => {"changed": true, "cmd": "echo Result output goes here. Some Exception number details : Exception from HRESULT\nSUCCESSFUL\n", "delta": "0:00:00.011982", "end": "2023-12-18 05:00:49.203555", "msg": "non-zero return code", "rc": 127, "start": "2023-12-18 05:00:49.191573", "stderr": "/bin/sh: line 1: SUCCESSFUL: command not found", "stderr_lines": ["/bin/sh: line 1: SUCCESSFUL: command not found"], "stdout": "Result output goes here. Some Exception number details : Exception from HRESULT", "stdout_lines": ["Result output goes here. Some Exception number details : Exception from HRESULT"]}

PLAY RECAP **************************************************************************************************************************************************
localhost                  : ok=1    changed=1    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0
原因分析

第一个任务的stdout包含两行内容:第一行是grep的输出,第二行是状态值SUCCESSFUL。直接在shell任务中使用echo {{ ExcepStatus.stdout }}时,换行符会被shell解析成命令分隔符,导致第二行的SUCCESSFUL被当成独立命令执行,从而触发报错。

解决方法

有两种方式可以提取目标字符串:

方式1:利用stdout_lines取最后一行

Ansible会自动将stdout按行拆分成列表stdout_lines,状态值在最后一行,直接取列表的最后一个元素即可:

- name: echo ExcepStatus
  shell: |
    echo "{{ ExcepStatus.stdout_lines[-1] }}"
  delegate_to: localhost

方式2:用正则提取状态字符串

通过regex_search过滤出SUCCESSFUL或FAILED:

- name: echo ExcepStatus
  shell: |
    echo "{{ ExcepStatus.stdout | regex_search('SUCCESSFUL|FAILED') }}"
  delegate_to: localhost

额外优化:让第一个任务只输出状态

如果不需要保留grep的输出,可以直接修改第一个任务,让它只输出最终状态,这样后续直接用{{ ExcepStatus.stdout }}就不会有问题:

- name: Parse result info
  shell: |
    echo "Result output goes here. Some Exception number details : Exception from HRESULT" | grep -q "Exception from HRESULT"
    if (( $? == 0)) ; then
      echo "SUCCESSFUL"
    else
      echo "FAILED"
    fi
  register: ExcepStatus
  delegate_to: localhost

这里用grep -q让grep不输出匹配内容,只返回退出码,这样第一个任务的stdout就只有状态值,后续任务直接使用{{ ExcepStatus.stdout }}即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 16:27:42