I'm trying to execute a shell script on a localhost using Ansible and display the output of the script. I've registered the output of the command using the shell module and stored it in the result variable. When I print result using the debug module, I see the dictionary duplicated. The dictionary contains both the stdout and stdout_lines fields, but I don't understand why the result is duplicated. Here's the playbook I'm using:
yaml
---
- name: Run shell script and display all keys in result
hosts: localhost
tasks:
- name: Create the shell script
copy:
dest: /tmp/multi_output.sh
content: |
#!/bin/bash
# Print multiple messages to STDOUT
for i in {1..101}
do
echo "Message $i to STDOUT"
done
sync # Forces the buffer to be written to disk
mode: '0755'
- name: Run the shell script
shell: "/tmp/multi_output.sh"
register: result
environment:
PYTHONUNBUFFERED: 1
- name: Display unique lines from 'stdout_lines'
debug:
var: result.stdout_lines
changed_when: false
- name: Display all keys in 'result'
debug:
var: result
Question: Why do I see two similar entries when I print result, as if the dictionary is duplicated (e.g., the stdout and stdout_lines fields)? How can I avoid this behavior and get a clear display of the output?
TASK [Visualizzare tutte le chiavi di 'result'] ********************************
ok: [localhost] => {
"result": {
"changed": true,
"cmd": "/tmp/multi_output.sh",
"delta": "0:00:00.016129",
"end": "2025-03-19 17:17:17.259092",
"failed": false,
"msg": "",
"rc": 0,
"start": "2025-03-19 17:17:17.242963",
"stderr": "",
"stderr_lines": [],
"stdout": "....",
"stdout_lines": [
"Messaggio 1 su STDOUT",
"Messaggio 2 su STDOUT",
"Messaggio 82 su STDOU"
}
ok: [localhost] => {
"result": {
"changed": true,
"cmd": "/tmp/multi_output.sh",
"delta": "0:00:00.016129",
"end": "2025-03-19 17:17:17.259092",
"failed": false,
"msg": "",
"rc": 0,
"start": "2025-03-19 17:17:17.242963",
"stderr": "",
"stderr_lines": [],
"stdout": "....",
"stdout_lines": [
"Messaggio 1 su STDOUT",
"Messaggio 2 su STDOUT",
"Messaggio 3 su STDOUT"
]
}
}
TASK [Visualizzare tutte le chiavi di 'result'] ********************************
ok: [localhost] => {
"result": {
"changed": true,
"cmd": "/tmp/multi_output.sh",
"delta": "0:00:00.016129",
"end": "2025-03-19 17:17:17.259092",
"failed": false,
"msg": "",
"rc": 0,
"start": "2025-03-19 17:17:17.242963",
"stderr": "",
"stderr_lines": [],
"stdout": "...",
"stdout_lines": [
"Messaggio 1 su STDOUT",
"Messaggio 2 su STDOUT",
"Messaggio 3 su STDOUT"
]
}
}
I'm trying to execute a shell script on a localhost using Ansible and display the output of the script. I've registered the output of the command using the shell module and stored it in the result variable. When I print result using the debug module, I see the dictionary duplicated. The dictionary contains both the stdout and stdout_lines fields, but I don't understand why the result is duplicated. Here's the playbook I'm using:
yaml
---
- name: Run shell script and display all keys in result
hosts: localhost
tasks:
- name: Create the shell script
copy:
dest: /tmp/multi_output.sh
content: |
#!/bin/bash
# Print multiple messages to STDOUT
for i in {1..101}
do
echo "Message $i to STDOUT"
done
sync # Forces the buffer to be written to disk
mode: '0755'
- name: Run the shell script
shell: "/tmp/multi_output.sh"
register: result
environment:
PYTHONUNBUFFERED: 1
- name: Display unique lines from 'stdout_lines'
debug:
var: result.stdout_lines
changed_when: false
- name: Display all keys in 'result'
debug:
var: result
Question: Why do I see two similar entries when I print result, as if the dictionary is duplicated (e.g., the stdout and stdout_lines fields)? How can I avoid this behavior and get a clear display of the output?
TASK [Visualizzare tutte le chiavi di 'result'] ********************************
ok: [localhost] => {
"result": {
"changed": true,
"cmd": "/tmp/multi_output.sh",
"delta": "0:00:00.016129",
"end": "2025-03-19 17:17:17.259092",
"failed": false,
"msg": "",
"rc": 0,
"start": "2025-03-19 17:17:17.242963",
"stderr": "",
"stderr_lines": [],
"stdout": "....",
"stdout_lines": [
"Messaggio 1 su STDOUT",
"Messaggio 2 su STDOUT",
"Messaggio 82 su STDOU"
}
ok: [localhost] => {
"result": {
"changed": true,
"cmd": "/tmp/multi_output.sh",
"delta": "0:00:00.016129",
"end": "2025-03-19 17:17:17.259092",
"failed": false,
"msg": "",
"rc": 0,
"start": "2025-03-19 17:17:17.242963",
"stderr": "",
"stderr_lines": [],
"stdout": "....",
"stdout_lines": [
"Messaggio 1 su STDOUT",
"Messaggio 2 su STDOUT",
"Messaggio 3 su STDOUT"
]
}
}
TASK [Visualizzare tutte le chiavi di 'result'] ********************************
ok: [localhost] => {
"result": {
"changed": true,
"cmd": "/tmp/multi_output.sh",
"delta": "0:00:00.016129",
"end": "2025-03-19 17:17:17.259092",
"failed": false,
"msg": "",
"rc": 0,
"start": "2025-03-19 17:17:17.242963",
"stderr": "",
"stderr_lines": [],
"stdout": "...",
"stdout_lines": [
"Messaggio 1 su STDOUT",
"Messaggio 2 su STDOUT",
"Messaggio 3 su STDOUT"
]
}
}
Share
Improve this question
edited Mar 19 at 17:58
Vito Custodero
asked Mar 19 at 17:46
Vito CustoderoVito Custodero
11 bronze badge
3
|
3 Answers
Reset to default 0When you register results from the shell:
module, you get the outpt twice, by design. One is the entire output in stdout
key, which is a single string and the other is a list with all the lines one-by-one in the stdout_lines
key. The content will be the same, you may decide which one fits better to the task you want to do with it.
By the way, you do not have to create a script file and the run it in a separate step. You can simply use the shell:
module with the |
operator, as you did with the copy:
module.
On the last line of your code, have...
var: result.stdout
...or...
var: result.stdout_lines
...whichever you prefer.
The issue was resolved by updating the versions of the libraries to:
ansible==4.10.0
ansible-core==2.11.12
ansible-runner==2.4.0
These versions are not the latest because I need to maintain compatibility with CentOS 7 systems running Python 2.7.
With this configuration, the issue no longer occurs.
stdout
is returned, Ansible always provides a list of strings, each containing one item per line from the original output. – U880D Commented Mar 19 at 19:29results.stdout
orresult.stdout_lines
depending on what you try to achieve. – U880D Commented Mar 19 at 19:33var: result.keys()
and resulting into an output ofresult.keys(): - changed - stdout - stderr - rc - cmd - start - end - delta - msg - stdout_lines - stderr_lines - failed
, a list of the dict keys. – U880D Commented Mar 19 at 19:34