Capturing Different Types of Output
In the previous step, we captured and displayed the standard output of our script. However, when executing scripts, there are several types of output we might want to capture:
- Standard Output (stdout): The normal output of the script
- Standard Error (stderr): Error messages and warnings
- Return Code (rc): The exit status of the script (0 typically means success, non-zero values indicate errors)
Let us create a new playbook that captures and displays all three types of output.
Create a new file named capture_all_output.yml
in the ~/project/ansible-output-demo
directory:
- Click on the "File" menu
- Select "New File"
- Save it as
capture_all_output.yml
in the ~/project/ansible-output-demo
directory
Add the following content to the capture_all_output.yml
file:
---
- name: Capture All Types of Script Output
hosts: local
gather_facts: no
tasks:
- name: Execute the info.sh script
command: "{{ playbook_dir }}/scripts/info.sh"
register: script_output
- name: Display standard output
debug:
msg: "Standard Output (stdout):"
- name: Display stdout content
debug:
var: script_output.stdout_lines
- name: Display standard error
debug:
msg: "Standard Error (stderr):"
- name: Display stderr content
debug:
var: script_output.stderr_lines
- name: Display return code
debug:
msg: "Return Code: {{ script_output.rc }}"
This playbook executes our script and then displays:
- The standard output using
script_output.stdout_lines
- The standard error using
script_output.stderr_lines
- The return code using
script_output.rc
Running the Enhanced Playbook
Let us run our new playbook:
cd ~/project/ansible-output-demo
ansible-playbook -i inventory capture_all_output.yml
You should see a comprehensive display of all three types of output:
PLAY [Capture All Types of Script Output] *****************************
TASK [Execute the info.sh script] *************************************
changed: [localhost]
TASK [Display standard output] ****************************************
ok: [localhost] => {
"msg": "Standard Output (stdout):"
}
TASK [Display stdout content] *****************************************
ok: [localhost] => {
"script_output.stdout_lines": [
"=== System Information ===",
"Hostname: ubuntu",
"Date: Tue Oct 17 12:40:22 UTC 2023",
"Kernel: 5.15.0-1031-aws",
"Memory:",
" total used free shared buff/cache available",
"Mem: 7.7Gi 1.2Gi 5.2Gi 12Mi 1.3Gi 6.3Gi",
"Swap: 0B 0B 0B",
"=== Standard Output ===",
"This is standard output",
"Hello from the script!"
]
}
TASK [Display standard error] *****************************************
ok: [localhost] => {
"msg": "Standard Error (stderr):"
}
TASK [Display stderr content] *****************************************
ok: [localhost] => {
"script_output.stderr_lines": [
"=== Standard Error ===",
"This is standard error",
"An example error message"
]
}
TASK [Display return code] ********************************************
ok: [localhost] => {
"msg": "Return Code: 0"
}
PLAY RECAP **********************************************************
localhost : ok=6 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Now we can see all types of output from our script:
- The standard output shows system information and our regular messages
- The standard error shows our error messages
- The return code is 0, indicating successful execution
Creating a Script with Errors
Let us create a script that will produce an error and return a non-zero exit code to see how Ansible handles it.
Create a new file named error.sh
in the scripts
directory:
- Click on the "File" menu
- Select "New File"
- Save it as
scripts/error.sh
in the ~/project/ansible-output-demo
directory
Add the following content to the error.sh
file:
#!/bin/bash
## Print some standard output
echo "Starting error demonstration script"
echo "This will appear in stdout"
## Print some standard error
echo "This will appear in stderr" >&2
echo "Error: Something went wrong!" >&2
## Exit with a non-zero code to indicate error
exit 1
Make the script executable:
chmod +x ~/project/ansible-output-demo/scripts/error.sh
Now let us create a playbook to execute this script and handle the error. Create a new file named handle_errors.yml
:
- Click on the "File" menu
- Select "New File"
- Save it as
handle_errors.yml
in the ~/project/ansible-output-demo
directory
Add the following content to the handle_errors.yml
file:
---
- name: Handle Script Errors
hosts: local
gather_facts: no
tasks:
- name: Execute the error script
command: "{{ playbook_dir }}/scripts/error.sh"
register: script_output
ignore_errors: yes
- name: Display standard output
debug:
var: script_output.stdout_lines
- name: Display standard error
debug:
var: script_output.stderr_lines
- name: Display return code
debug:
msg: "Return Code: {{ script_output.rc }}"
- name: Check if script failed
debug:
msg: "The script failed with return code {{ script_output.rc }}"
when: script_output.rc != 0
Notice the addition of ignore_errors: yes
which tells Ansible to continue running the playbook even if the command fails (returns a non-zero exit code).
Let us run this playbook:
ansible-playbook -i inventory handle_errors.yml
You should see output similar to the following:
PLAY [Handle Script Errors] *******************************************
TASK [Execute the error script] ***************************************
changed: [localhost]
TASK [Display standard output] ****************************************
ok: [localhost] => {
"script_output.stdout_lines": [
"Starting error demonstration script",
"This will appear in stdout"
]
}
TASK [Display standard error] *****************************************
ok: [localhost] => {
"script_output.stderr_lines": [
"This will appear in stderr",
"Error: Something went wrong!"
]
}
TASK [Display return code] ********************************************
ok: [localhost] => {
"msg": "Return Code: 1"
}
TASK [Check if script failed] *****************************************
ok: [localhost] => {
"msg": "The script failed with return code 1"
}
PLAY RECAP **********************************************************
localhost : ok=5 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
This example demonstrates how to:
- Capture output from a script that produces an error
- Continue the playbook execution despite the error
- Conditionally execute tasks based on the script's return code
In the next step, we will explore more advanced use cases and best practices for working with script output in Ansible.