Regarding the comments "You need to register the output of the command in order for Ansible to store it." and "I tried register before, but I cannot find a way to use the register variable in the shell of other play." you may have look into the following minimal example playbook
---
- hosts: localhost
become: true
gather_facts: false
tasks:
- name: 4. Verify key generation
shell:
cmd: "gpg --list-secret-keys --keyid-format=long | sed '4!d' | tr -d ' '"
register: VAR
- name: 6. Echo GPG ID
shell:
cmd: "echo {{ VAR.stdout_lines }}"
register: result
- name: Show result
debug:
var: result
or a more generic
---
- hosts: localhost
become: false
gather_facts: false
tasks:
- name: Echo example 1
shell:
cmd: "echo 12:34:56:78:90:AB:CD:EF"
register: VAR
- name: Echo example 2
shell:
cmd: "echo {{ VAR.stdout_lines }}"
register: result
- name: Show registered variable
debug:
var: result
- name: Show result content only
debug:
msg: "{{ result }}"
as it shows you how to get familiar with registering, return values and data structures.
Further Documenation
- Registering variables
- Common Return Values
shellReturn Valuesdebugmodule – Print statements during execution
Ansible: Use stdout_lines from registered variable which uses loop in shell module - Stack Overflow
register, with_items and stdout_lines
ansible - Take shell cmd stdout_lines and create dict from output - DevOps Stack Exchange
How to grab last two lines from ansible (register stdout) initialization of kubernetes cluster - Stack Overflow
I think you can register the result to a variable, then print with debug.
- name: print to stdout
command: echo "hello"
register: hello
- debug: msg="{{ hello.stdout }}"
- debug: msg="{{ hello.stderr }}"
Instead of stdout I would suggest using stdout_lines. For multiline output this is much nicer, e.g.
- hosts: all
tasks:
- name: Run ls.sh and output "ls /"
script: ls.sh
register: out
- debug: var=out.stdout_lines
gives
TASK: [debug var=out.stdout_lines] ********************************************
ok: [local] => {
"var": {
"out.stdout_lines": [
"total 61",
"lrwxrwxrwx 1 root root 7 Feb 15 2015 bin -> usr/bin",
"drwxr-xr-x 6 root root 1024 Aug 24 22:08 boot",
"drwxr-xr-x 22 root root 3580 Sep 8 18:41 dev",
[...]
"drwxr-xr-x 9 root root 4096 Aug 25 19:14 usr",
"drwxr-xr-x 13 root root 4096 Feb 25 2015 var"
]
}
}
Regarding real time output for debugging purposes there is a closed bug report https://github.com/ansible/ansible/issues/3887#issuecomment-54672569 discussing the reasons why this is not possible and will not be implemented.
It's my understanding that using register with a loop and trying to output the information in stdout format, Ansible stores the results in a more complex way and it's not that easy to access the .stdout.
Here is what I'm trying to work with:
- name: "vs_profile_type"
prompt: "enter the profile to run your pre-checks against [Enter in the following format: tcp tcp, http http]"
private: no
tasks:
- name : Checking which LTM is active....
bigip_command:
server: "{{ inventory_hostname }}"
user: "{{ remote_username }}"
password: "{{ remote_passwd }}"
commands:
- "tmsh show sys failover"
validate_certs: no
delegate_to: localhost
register: Active_LTM
- name: The active LTMs management IP is....
block:
- debug:
var: Active_LTM.stdout[0]
- name: Profile_Pre-check
bigip_command:
server: "{{ inventory_hostname }}"
user: "{{ remote_username }}"
password: "{{ remote_passwd }}"
commands:
- "tmsh list ltm profile {{ item }}"
validate_certs: no
delegate_to: localhost
with_items:
- "{{ vs_profile_type.split(',') }}"
when: "'active' in Active_LTM['stdout'][0]"
register: Active_LTM_Pre_Checks
- name: Please verify the profile pre-checks are correct
debug:
var: Active_LTM_Pre_Checks.stdout_linesThe problem comes when the play gets to the debug section and it throws an error saying that the variable "Active_LTM_Pre_Checks.stdout_lines" is not defined. I've done some searching but haven't been able to find a solution yet on how to accomplish this
Select last 2 lines from the list stdout_lines
Copy- local_action: copy content={{ init_output.stdout_lines[-2:] }} dest="./join-command"
It's possible to format the lines in a block. For example
Copy - local_action:
module: copy
content: |
{{ init_output.stdout_lines[-2] }}
{{ init_output.stdout_lines[-1] }}
dest: "./join-command"
To append the lines in a loop try
Copy - local_action:
module: lineinfile
path: "./join-command"
line: "{{ item }}"
insertafter: EOF
create: true
loop: "{{ init_output.stdout_lines[-2:] }}"
I encountered this kind of issue and did not want to copy the join command to a local file so I did a set_fact instead this way:
Copy- set_fact:
join_cmd: '{{ init_output.stdout_lines[-2][:-2] }}{{ init_output.stdout_lines[-1] }}'
I have the following playbook:
---
- hosts: cisco
gather_facts: no
connection: local
vars_files:
- secrets.yaml
- commands.yaml
tasks:
- name: DEFINE PROVIDER
set_fact:
provider:
host: "{{ inventory_hostname }}"
username: "{{ creds['username'] }}"
password: "{{ creds['password'] }}"
auth_pass: "{{ creds['auth_pass'] }}"
- name: RUN COMMANDS ON DEVICE
ios_command:
provider: "{{ provider }}"
# transport: cli
commands:
"{{ item.command }}"
register: result
with_items: "{{ commands }}"
- debug: var=result.stdout_lineswhich references a 'commands.yaml' file that I want the 'RUN COMMANDS ON DEVICE' task to iterate over. The commands.yaml file has a format like:
--- commands: - command: show version - command: show cdp neighbor
When I run the playbook with -vvv I do see the command output, but I continue to get an error stating that result.stdout_lines is not defined. I've also tried to move the 'register: result' line to below the 'with_items: "{{ commands }}"' line, but that has no effect.
Is there a way for me to iterate of the values in the 'commands.yaml' file and have the output from each 'registered' to a variable that I can later reference?
Thanks.