Formatting Shell Command Output in Ansible Playbooks

Nov 23, 2025 · Programming · 8 views · 7.8

Keywords: Ansible | Shell Output | Playbook Debugging

Abstract: This technical article provides an in-depth analysis of obtaining clean, readable output formats when executing shell commands within Ansible Playbooks. By examining the differences between direct ansible command execution and Playbook-based approaches, it details the optimal solution using register variables and the debug module with stdout_lines attribute, effectively resolving issues with lost newlines and messy dictionary structures in Playbook output for system monitoring and operational tasks.

Problem Background and Challenges

In automated operations scenarios, Ansible as a mainstream configuration management tool frequently requires executing system monitoring commands to gather host status information. Users typically employ commands like ps -eo pcpu,user,args | sort -r -k1 | head -n5 to monitor processes with highest CPU utilization. Direct usage of the ansible command-line tool perfectly outputs formatted results:

localhost | success | rc=0 >>
0.0 root     /sbin/init
0.0 root     [kthreadd]
0.0 root     [ksoftirqd/0]
0.0 root     [migration/0]

However, when migrating the same command to Playbook execution, the output becomes difficult to read:

changed: [localhost] => {"changed": true, "cmd": "ps -eo pcpu,user,args | sort -r -k1 head -n5 ", "delta": "0:00:00.015337", "end": "2013-12-13 10:57:25.680708", "rc": 0, "start": "2013-12-13 10:57:25.665371", "stderr": "", "stdout": "47.3 xxx    Xvnc4 :24 -desktop xxx:24 (xxx) -auth /home/xxx/.Xauthority -geometry 1920x1200\n...."

Core Solution

Through in-depth analysis of Ansible module working principles, we identify the root cause lies in Playbook's default output format handling mechanism. When using the shell module to execute commands, the returned result is a dictionary object containing complete execution information, where the stdout field stores the command's standard output content, but this field converts newlines into \n escape characters, causing formatting issues during direct output.

The optimal solution leverages Ansible's variable registration functionality and specific attributes of the debug module:

- hosts: all
  gather_facts: no
  tasks:
    - shell: ps -eo pcpu,user,args | sort -r -k1 | head -n5
      register: ps

    - debug: var=ps.stdout_lines

Technical Principle Analysis

The register keyword saves the shell module's execution result to a specified variable, which contains several important fields:

The key advantage of the stdout_lines attribute is its automatic splitting of output content into a Python list based on newline characters, with each list element corresponding to one line of original output. When outputting this attribute using the debug module, Ansible displays the list content in a structured manner, preserving the original line formatting.

Practical Application Results

After implementing this solution, the output format shows significant improvement:

ok: [host1] => {
    "ps.stdout_lines": [
        "%CPU USER     COMMAND",
        " 1.0 root     /usr/bin/python",
        " 0.6 root     sshd: root@notty ",
        " 0.2 root     java",
        " 0.0 root     sort -r -k1"
    ]
}

This format not only preserves the original layout of command output but also provides clear hierarchical structure for quick identification of key information.

Extended Application Scenarios

This technical approach can be widely applied to various system monitoring scenarios:

By reasonably combining different Shell commands and output processing techniques, powerful automated monitoring systems can be constructed.

Best Practice Recommendations

In actual production environments, we recommend following these best practices:

  1. For critical monitoring tasks, always use the register and stdout_lines combination to ensure output readability
  2. Add appropriate error handling logic in Playbooks, checking the rc return code
  3. For complex outputs, consider preprocessing with tools like sed, awk
  4. Consider using lineinfile or copy modules to save important outputs to files

The advantage of this method lies in maintaining the elegance of Ansible's declarative configuration while providing necessary flexibility to handle command-line tool output format requirements.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.