How to correctly print a multiline stdout?

20,920 views
Skip to first unread message

Nicolas Grilly

unread,
Sep 4, 2013, 11:01:15 AM9/4/13
to ansible...@googlegroups.com
Hello,

We run our database migrations using Ansible with something along these lines:

    - name: Run database migrations
      command: env/bin/python migrate.py -q chdir=$project_dir/releases/$release_date
      register: result
      changed_when: result.stdout

migrate.py prints the list of applied migrations to stdout.

We try to print this list because our developers want some feedback about which migrations were applied:

    - debug: msg="{{result.stdout}}"
      when: result.stdout

But all new lines are escaped to \n, which makes the output quite difficult to read.

Is there any solution to this?

In your own projects, how do you execute your database migrations? Do you try to get some feedback as what we try to achieve here? Or do you use another approach?

Thanks,

-- Nicolas

Firat Arig

unread,
Sep 5, 2013, 7:18:31 AM9/5/13
to ansible...@googlegroups.com
Hi there,

Printing lines separately can be done like

    - name: Run database migrations
      command: env/bin/python migrate.py -q chdir=$project_dir/releases/$release_date
      register: result
      changed_when: result.stdout_lines

    - debug: msg="{{item}}"
      with_items: result.stdout_lines
      when: result.stdout_lines

Cheers,

-- Firat


4 Eylül 2013 Çarşamba 18:01:15 UTC+3 tarihinde Nicolas Grilly yazdı:

Nicolas Grilly

unread,
Sep 6, 2013, 10:29:39 AM9/6/13
to ansible...@googlegroups.com
On Thursday, September 5, 2013 1:18:31 PM UTC+2, Firat Arig wrote:
Printing lines separately can be done like

    - name: Run database migrations
      command: env/bin/python migrate.py -q chdir=$project_dir/releases/$release_date
      register: result
      changed_when: result.stdout_lines

    - debug: msg="{{item}}"
      with_items: result.stdout_lines
      when: result.stdout_lines

Waouh, that's very clever :)

But the output is still a bit "weird" for this use case:

ok: [host.domain.net] => (item=foo) => {"item": "foo", "msg": "foo"}
ok: [host.domain.net] => (item=bar) => {"item": "bar", "msg": "bar"}
...

Is there another way?

-- Nicolas
 

Michael DeHaan

unread,
Sep 6, 2013, 5:01:48 PM9/6/13
to ansible...@googlegroups.com
Easiest way to debug this is just to use "-v" and it will output the previous data.





--
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-proje...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.



--
Michael DeHaan <mic...@ansibleworks.com>
CTO, AnsibleWorks, Inc.
http://www.ansibleworks.com/

Nicolas Grilly

unread,
Sep 6, 2013, 7:59:07 PM9/6/13
to ansible...@googlegroups.com
On Fri, Sep 6, 2013 at 11:01 PM, Michael DeHaan <mic...@ansibleworks.com> wrote:
Easiest way to debug this is just to use "-v" and it will output the previous data.

Yes, but if result.stdout contains new lines, they will show up escaped as \n instead of "real" new lines, which makes it difficult to read. Any advice on this?


--
Nicolas Grilly
Vocation City  |  Web Recruitment Platform
Garden  |  Web Software Architects

Jesse Keating

unread,
Sep 6, 2013, 9:29:57 PM9/6/13
to ansible...@googlegroups.com
On Sep 6, 2013, at 4:59 PM, Nicolas Grilly <nic...@vocationcity.com> wrote:
>
> On Fri, Sep 6, 2013 at 11:01 PM, Michael DeHaan <mic...@ansibleworks.com> wrote:
> Easiest way to debug this is just to use "-v" and it will output the previous data.
>
> Yes, but if result.stdout contains new lines, they will show up escaped as \n instead of "real" new lines, which makes it difficult to read. Any advice on this?

You could try:

debug: msg="{{ print(result.stdout) }}"

The print() function should turn the \n's into new lines.

-jlk

Nicolas Grilly

unread,
Sep 7, 2013, 7:13:34 AM9/7/13
to ansible...@googlegroups.com
On Sat, Sep 7, 2013 at 3:29 AM, Jesse Keating <jkea...@j2solutions.net> wrote:
You could try:

debug: msg="{{ print(result.stdout) }}"

The print() function should turn the \n's into new lines.

It fails with the following error:

TASK: [debug msg="{{print(result.stdout)}}"] ********************************** 
fatal: [gardentechno.typhon.net] => One or more undefined variables: 'print' is undefined

-- Nicolas

Michael DeHaan

unread,
Sep 7, 2013, 8:47:27 AM9/7/13
to ansible...@googlegroups.com
Yep, we don't export random functions here.

"{{ }}" is a call for string templating, it is not a place to insert arbitrary python code.

You wouldn't want os.unlink() in there either!  :)




--
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-proje...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Nicolas Grilly

unread,
Sep 7, 2013, 9:16:28 AM9/7/13
to ansible...@googlegroups.com
On Sat, Sep 7, 2013 at 2:47 PM, Michael DeHaan <mic...@ansibleworks.com> wrote:
Yep, we don't export random functions here.

"{{ }}" is a call for string templating, it is not a place to insert arbitrary python code.

You wouldn't want os.unlink() in there either!  :)

Hello Michael,

Yes, I know :) It was the purpose of the small pull request James accepted yesterday to update the documentation about Jinja2 expressions in playbooks.

This is why I was a quite surprised by Jesse suggestion. I just gave it a try to make sure I was not missing something, and hopefully it doesn't work :)

Any idea on how to solve the problem I stated at the start of this discussion: We have a playbook that executes database schema migrations, and I want to print the list of applied migrations on the console?... The list of applied migrations is printed on stdout by the migration command.

Cheers,

Nicolas

Firat Arig

unread,
Sep 9, 2013, 2:29:38 AM9/9/13
to ansible...@googlegroups.com
I don't think what you want it is currently possible through ansible. Polling the output of a file would be a less hacky way to address your problem.

7 Eylül 2013 Cumartesi 16:16:28 UTC+3 tarihinde Nicolas Grilly yazdı:

Michael DeHaan

unread,
Sep 9, 2013, 10:46:44 AM9/9/13
to ansible...@googlegroups.com
It seems what we really want is a better way for the debug module to work with structured and multiline data, like:

debug: var=foo.stdout_lines




--
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-proje...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Jason Freeman

unread,
Sep 10, 2013, 5:06:39 PM9/10/13
to ansible...@googlegroups.com
If you are really looking for specialized output, why bother using debug module? Add the following task and create some simple script to parse. The inventory_hostname will give the remote host corresponding to the stdout (you don't want to mix those up).

    - local_action: command bash /my/local/path/writer.sh "$inventory_hostname" "{{ item }}"
      with_items: result.stdout_lines
      when: result.stdout

A simple bash script on your local machine (writer.sh)...

    #!/bin/sh
    echo $1 $2 >> out.log

I came looking for something similar, but there doesn't seem to be a great way to format output (built in).

hope it helps

Michael DeHaan

unread,
Sep 11, 2013, 8:24:34 AM9/11/13
to ansible...@googlegroups.com
Probably because it requires writing bash in the middle of your Ansible playbook, which is something we want to avoid people having to do.

It would be much better to enhance the debug module as it would make the playbook more readable without resorting to hijinks.


Brad Smith

unread,
May 5, 2015, 1:16:58 PM5/5/15
to ansible...@googlegroups.com
Did anything ever come of this? I would really like to be able to print friendly "Provisioning succeeded! Here's what to do next..." messages at the end of some of my playbooks.

--Brad

Nicolas Grilly

unread,
May 5, 2015, 3:17:34 PM5/5/15
to ansible...@googlegroups.com
On Tuesday, May 5, 2015 at 7:16:58 PM UTC+2, Brad Smith wrote:
Did anything ever come of this? I would really like to be able to print friendly "Provisioning succeeded! Here's what to do next..." messages at the end of some of my playbooks.

Not to my knowledge. I'd like to have a solution :-) 

Brian Coca

unread,
May 5, 2015, 3:45:56 PM5/5/15
to ansible...@googlegroups.com
everything that has stdout, shoudl have stdout_lines, which is already
multiline, for those that don't just use split('/n').


--
Brian Coca

Zhendong Zhao

unread,
Jul 8, 2022, 12:03:08 PM7/8/22
to Ansible Project
Hi @Nicolas Grilly,
I met the same issue... It's year 2022 already, did you get any solution? thanks.

Nicolas Grilly

unread,
Jul 9, 2022, 6:21:27 AM7/9/22
to ansible...@googlegroups.com
On Fri, Jul 8, 2022 at 6:03 PM Zhendong Zhao <zdz...@gmail.com> wrote:
I met the same issue... It's year 2022 already, did you get any solution? thanks.

Nope, no solution. 

Felix Fontein

unread,
Jul 9, 2022, 6:34:21 AM7/9/22
to ansible...@googlegroups.com
Hi,

there are multiple solutions, even if there's no perfect one that
works out of the box:

1. Use `debug: msg="{{ result.stdout_lines }}"`. Not perfect, but
a lot better to read than `debug: msg="{{ result.stdout }}"`.

2. Check out the many callback plugins that exist:
https://docs.ansible.com/ansible/latest/collections/index_callback.html
Maybe one of them supports this? If not, you could write your own.
(I would try
https://docs.ansible.com/ansible/latest/collections/community/general/diy_callback.html
- it seems to be very configurable, maybe it can do this?)

3. You could write an action plugin similar to `debug` that prints the
given parameter without any quoting.

(If someone wants to contribute something like that to
community.general, I'm happy to review it.)

Cheers,
Felix

Vladimir Botka

unread,
Jul 9, 2022, 10:45:48 AM7/9/22
to Zhendong Zhao, ansible...@googlegroups.com
Try *yaml* callback
https://docs.ansible.com/ansible/latest/collections/community/general/yaml_callback.html

For example, the playbook

shell> cat pb.yml
- hosts: localhost
vars:
result:
stdout: |
line1
line2
line3
tasks:
- debug:
var: result.stdout

gives (abridged)

shell> ANSIBLE_STDOUT_CALLBACK=yaml ansible-playbook pb.yml

ok: [localhost] =>
result.stdout: |-
line1
line2
line3

--
Vladimir Botka
Reply all
Reply to author
Forward
0 new messages