ansibleansible-inventory

Extract values from stdout output using Ansible


I am running a command to get the status of tomcat and registering it in a variable. How do i extract the specific output of that command and put it in a variable to check further

Play -

- name: Check the State og tomcat service
   shell: "svcs tomcat"
   register: tomcat_status

 - name: Show captured processes
   debug:
     msg: "{{ tomcat_status.stdout_lines|list }}"

The output of the above is -

 server1 ok: {
    "changed": false,
    "msg": [
        "STATE          STIME    FMRI",
        "online         20:11:48 svc:/network/tomcat:tomcat"
    ]
}

How do i extract the value of STATE here? I want to know if it's online or disabled or shutdown etc.

NOTE - Output with -vvvv

 server1 done: {
    "changed": true,
    "cmd": "svcs tomcat",
    "delta": "0:00:00.025711",
    "end": "2020-05-11 12:43:43.323017",
    "invocation": {
        "module_args": {
            "_raw_params": "svcs tomcat",
            "_uses_shell": true,
            "argv": null,
            "chdir": null,
            "creates": null,
            "executable": null,
            "removes": null,
            "stdin": null,
            "stdin_add_newline": true,
            "strip_empty_ends": true,
            "warn": false
        }
    },
    "rc": 0,
    "start": "2020-05-11 12:43:43.297306",
    "stderr": "",
    "stderr_lines": [],
    "stdout": "STATE          STIME    FMRI\nonline         20:11:48 svc:/network/tomcat:tomcat",
    "stdout_lines": [
        "STATE          STIME    FMRI",
        "online         20:11:48 svc:/network/tomcat:tomcat"
    ]
}

Solution

  • Based on your debug about, tomcat_status.stdout_lines is a list (you don't need the |list filter here because it's already a list) that looks like:

    [
      "STATE          STIME    FMRI",
      "online         20:11:48 svc:/network/tomcat:tomcat"
    ]
    

    To get the STATE value, you need the first field from the second line. So:

    - set_fact:
        tomcat_state: "{{ tomcat_status.stdout_lines.1.split().0 }}"
    

    That takes the second line (tomcat_status.stdout_lines.1) then splits it on whitespace (.split()), and then takes the first value (.0).

    Here's a complete test:

    - hosts: localhost
      vars:
        tomcat_status:
          stdout_lines:
            - "STATE          STIME    FMRI"
            - "online         20:11:48 svc:/network/tomcat:tomcat"
    
      tasks:
        - set_fact:
            tomcat_state: "{{ tomcat_status.stdout_lines.1.split().0 }}"
    
        - debug:
            var: tomcat_state
    

    Running that playbook results in:

    
    PLAY [localhost] *****************************************************************************
    
    TASK [set_fact] ******************************************************************************
    ok: [localhost]
    
    TASK [debug] *********************************************************************************
    ok: [localhost] => {
        "tomcat_state": "online"
    }
    
    PLAY RECAP ***********************************************************************************
    localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0