How to save stdout_lines to a file without losing the newlines

3,487 views
Skip to first unread message

jean-christophe manciot

unread,
Nov 7, 2016, 10:07:36 AM11/7/16
to Ansible Project
Hi everyone,

Considering a variable {{ table.stdout_lines ]] containing the following when printing it out on the terminal:
TASK [save_table : Printing the returned table] *****************************************************************************************************************************
ok: [IOSv_L2_10] => {
    "table.stdout_lines": [
        [
            "Extended IP access list authorized-snmp-nms", 
            "    10 permit ip host 172.21.100.1 host 172.21.100.210 log", 
            "Extended IP access list preauth_ipv4_acl (per-user)", 
            "    10 permit udp any any eq domain", 
            "    20 permit tcp any any eq domain", 
            "    30 permit udp any eq bootps any", 
            "    40 permit udp any any eq bootpc", 
            "    50 permit udp any eq bootpc any", 
            "    60 deny ip any any", 
            "IPv6 access list preauth_ipv6_acl (per-user)", 
            "    permit udp any any eq domain sequence 10", 
            "    permit tcp any any eq domain sequence 20", 
            "    permit icmp any any nd-ns sequence 30", 
            "    permit icmp any any nd-na sequence 40", 
            "    permit icmp any any router-solicitation sequence 50", 
            "    permit icmp any any router-advertisement sequence 60", 
            "    permit icmp any any redirect sequence 70", 
            "    permit udp any eq 547 any eq 546 sequence 80", 
            "    permit udp any eq 546 any eq 547 sequence 90", 
            "    deny ipv6 any any sequence 100"
        ]
    ]
}

I need to save those lines into a local file, easy right?
- name: Saving "{{ item }}" into local file
  local_action: copy content="{{ table.stdout_lines }}" dest="{{ dest_file }}"

Unfortunately, all newlines are lost rendering the file difficult to read:
[["Extended IP access list authorized-snmp-nms", "    10 permit ip host 172.21.100.1 host 172.21.100.210 log", "Extended IP access list preauth_ipv4_acl (per-user)", "    10 permit udp any any eq domain", "    20 permit tcp any any eq domain", "    30 permit udp any eq bootps any", "    40 permit udp any any eq bootpc", "    50 permit udp any eq bootpc any", "    60 deny ip any any", "IPv6 access list preauth_ipv6_acl (per-user)", "    permit udp any any eq domain sequence 10", "    permit tcp any any eq domain sequence 20", "    permit icmp any any nd-ns sequence 30", "    permit icmp any any nd-na sequence 40", "    permit icmp any any router-solicitation sequence 50", "    permit icmp any any router-advertisement sequence 60", "    permit icmp any any redirect sequence 70", "    permit udp any eq 547 any eq 546 sequence 80", "    permit udp any eq 546 any eq 547 sequence 90", "    deny ipv6 any any sequence 100"]]

Anyone has a brilliant simple idea to save {{ table.stdout_lines }} with all newlines in the file?

Kai Stian Olstad

unread,
Nov 7, 2016, 10:39:18 AM11/7/16
to ansible...@googlegroups.com
On 07. nov. 2016 16:07, jean-christophe manciot wrote:
> Anyone has a brilliant simple idea to save {{ table.stdout_lines }} with
> all newlines in the file?

Yes, use table.stdout :-)

--
Kai Stian Olstad

J Hawkesworth

unread,
Nov 7, 2016, 10:41:05 AM11/7/16
to Ansible Project
Have you tried the following?

{{table.stdout_lines|join('\n') }} 

Not tested but sounds like it might do what you want.

Jon

jean-christophe manciot

unread,
Nov 7, 2016, 11:17:31 AM11/7/16
to Ansible Project
@Kai Stian Olstad: stdout adds literal '\n' to each line
@Jon: |join('\n') has no effect on stdout_lines

However, if I combine both proposals into table.stdout|join('\n'), it works! Thanks guys ;)

For instance:
          Mac Address Table
-------------------------------------------

Vlan    Mac Address       Type        Ports
----    -----------       --------    -----
   1    0000.ab03.c600    DYNAMIC     Gi0/1
   1    0000.ab41.1f00    DYNAMIC     Gi1/1
   1    0000.ab55.1900    DYNAMIC     Gi1/0
   1    0000.ab8d.1e00    DYNAMIC     Gi0/2
   1    0000.abb9.4600    DYNAMIC     Gi2/2
   1    0000.abc8.ec00    DYNAMIC     Gi1/2
   1    0000.abe0.0600    DYNAMIC     Gi0/3
   1    2e05.f26f.bf83    DYNAMIC     Gi0/0
Total Mac Addresses for this criterion: 8

Kai Stian Olstad

unread,
Nov 7, 2016, 11:27:57 AM11/7/16
to ansible...@googlegroups.com
On 07. nov. 2016 17:17, jean-christophe manciot wrote:
> @Kai Stian Olstad: stdout adds literal '\n' to each line

That's strange, i use that all the time and get correct newlines.

--
Kai Stian Olstad

jean-christophe manciot

unread,
Nov 7, 2016, 12:10:59 PM11/7/16
to Ansible Project
I suppose it depends on how the data are returned by the target device, which is not a Linux server here, but a Cisco IOS networking device, which is a very specific beast.

Peter Sprygada

unread,
Nov 7, 2016, 1:42:34 PM11/7/16
to ansible...@googlegroups.com
Write the stdout var instead.

- name: Saving "{{ item }}" into local file
  local_action: copy content="{{ table.stdout[0] }}" dest="{{ dest_file }}"

On Mon, Nov 7, 2016 at 12:10 PM, jean-christophe manciot <actionm...@gmail.com> wrote:
I suppose it depends on how the data are returned by the target device, which is not a Linux server here, but a Cisco IOS networking device, which is a very specific beast.

--
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-project+unsubscribe@googlegroups.com.
To post to this group, send email to ansible-project@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ansible-project/9cdbfee1-8335-45fe-8c57-95656c3c30f6%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

jean-christophe manciot

unread,
Nov 7, 2016, 1:53:30 PM11/7/16
to Ansible Project
Thanks, it's even simpler and it seems to function correctly in all cases.

jean-christophe manciot

unread,
Nov 8, 2016, 10:10:14 AM11/8/16
to Ansible Project
@Peter Sprygada: I'm now facing a more complicated case where I have trouble accessing stdout[0]:

- name: Fetching PACL_Table on all L2 interfaces from the remote node
  ios_command:
        provider: "{{ connections.ssh }}"
        commands:
          - "show run interface {{ net_item.key }} | include ^interface|access-group"
  with_dict: "{{ ansible_net_interfaces }}"
  when: net_item.value.ipv4.address is not defined
  loop_control:
    loop_var: net_item
  register: pacl_tables

- name: Printing pacl_tables.results
  debug: var=pacl_tables.results

...leads to:
ok: [IOSv_L2_10] => {
    "pacl_tables.results": [
        {
            "_ansible_item_label": {
                "key": "GigabitEthernet1/2", 
                "value": {
                    "bandwidth": 1000000, 
                    "description": "Connected to [u'IOSv_Leaf_16.actionmystique.net'] on its port [u'Gi0/0']", 
                    "duplex": "Full", 
                    "ipv4": null, 
                    "lineprotocol": "up (connected) ", 
                    "macaddress": "0036.2586.7e06", 
                    "mediatype": "unknown media type", 
                    "mtu": 1500, 
                    "operstatus": "up", 
                    "type": "iGbE"
                }
            }, 
            "_ansible_item_result": true, 
            "_ansible_no_log": false, 
            "_ansible_parsed": true, 
            "changed": false, 
            "invocation": {
                "module_args": {
                    "auth_pass": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER", 
                    "authorize": true, 
                    "commands": [
                        "show run interface GigabitEthernet1/2 | include ^interface|access-group"
                    ], 
                    "host": "172.21.100.210", 
                    "interval": 1, 
                    "match": "all", 
                    "password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER", 
                    "port": 22, 
                    "provider": {
                        "auth_pass": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER", 
                        "authorize": true, 
                        "host": "172.21.100.210", 
                        "password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER", 
                        "port": 22, 
                        "ssh_keyfile": "~/.ssh/id_rsa", 
                        "timeout": 10, 
                        "transport": "cli", 
                        "username": "admin", 
                        "version": 2
                    }, 
                    "retries": 10, 
                    "ssh_keyfile": "/root/.ssh/id_rsa", 
                    "timeout": 10, 
                    "transport": "cli", 
                    "use_ssl": true, 
                    "username": "admin", 
                    "validate_certs": true, 
                    "wait_for": null
                }, 
                "module_name": "ios_command"
            }, 
            "net_item": {
                "key": "GigabitEthernet1/2", 
                "value": {
                    "bandwidth": 1000000, 
                    "description": "Connected to [u'IOSv_Leaf_16.actionmystique.net'] on its port [u'Gi0/0']", 
                    "duplex": "Full", 
                    "ipv4": null, 
                    "lineprotocol": "up (connected) ", 
                    "macaddress": "0036.2586.7e06", 
                    "mediatype": "unknown media type", 
                    "mtu": 1500, 
                    "operstatus": "up", 
                    "type": "iGbE"
                }
            }, 
            "stdout": [
                "show run interface GigabitEthernet1/2 | include ^interface|access-$terface GigabitEthernet1/2 | include ^interface|access-g         oup\ninterface GigabitEthernet1/2"
            ], 
            "stdout_lines": [
                [
                    "show run interface GigabitEthernet1/2 | include ^interface|access-$terface GigabitEthernet1/2 | include ^interface|access-g         oup", 
                    "interface GigabitEthernet1/2"
                ]
            ], 
            "warnings": []
        }, 
...repeated n times, for all found L2 interfaces.

However, I cannot access stdout[0] for all these interfaces with:
- name: Printing pacl_tables.results.stdout
  debug: var=print_item.stdout[0]
  with_dict: "{{ pacl_tables.results }}"
  loop_control:
    loop_var: print_item
... which leads to:
fatal: [IOSv_L2_10]: FAILED! => {"failed": true, "msg": "with_dict expects a dict"}

How can we correctly access a table of results? (I'm not mentioning the issue with the strange result itself.)
Reply all
Reply to author
Forward
0 new messages