0

So I got the following task:

- name: "Use echo."
  shell: echo -e "First Line\n " > "/tmp/{{ ansible_date_time.date }}_test.txt"
  delegate_to: localhost
  become: 'no'
  changed_when: 'false'
  run_once: 'yes'

When looking at the resulting file I get:

-e First Line
<newline printed properly>

What I want is:

First Line
<newline printed properly>

I basically tried every form of quoting, so what am I missing?

Thorian93
  • 753

2 Answers2

2

Here is a workaround, using the binary /bin/echo instead of the shell built-in echo command.

- name: "Use echo."
  shell: /bin/echo -e "First Line\n " > "/tmp/{{ ansible_date_time.date }}_test.txt"
  delegate_to: localhost
  become: 'no'
  changed_when: 'false'
  run_once: 'yes'

Here's the explanation regarding shell built-in echo command:

$ which echo
echo: shell built-in command

$ ls -l /bin/echo -rwxr-xr-x 1 root root 39256 Sep 5 2019 /bin/echo

And this is the package that provides the /bin/echo binary:

$ dpkg -S /bin/echo  # Ubuntu/Debian distro
coreutils: /bin/echo
GMaster
  • 6,322
  • I used this fix, as your answer was quite fast. But i think I will migrate to using printf as it feels cleaner. But thank you for your quick an well explained answer! – Thorian93 Oct 07 '20 at 09:20
2

For various historical reasons, different versions of echo treat their arguments differently...

$ bash -c 'echo -e hello'
hello
$ dash -c 'echo -e hello'
-e hello

Dash is Debian's and Ubuntu's /bin/sh, and the shell most programs escaping to the shell are likely to use. That's probably what you're hitting here.

You can avoid the incompatibilities by using printf instead. It's a standard tool, and has less such incompatibilities (and always processes \n etc.):

shell: printf "First Line\n " > "/tmp/{{ ansible_date_time.date }}_test.txt"

As for using quotes, options are processed by the utility itself, while quotes are completely a shell construct, so regardless of if you use e.g. echo '-e' or echo -e, what is seen by echo itself is exactly the same.

See also:

ilkkachu
  • 138,973
  • I went with the /bin/echo solution as it was the first answer, but I like this approach better, as it feels cleaner and you explain the exact behavior I see. I am on Debian, so this is most probably a dash situation. Marking your answer as the solution as it is just slightly better fit for my question than the one by @GMaster. – Thorian93 Oct 07 '20 at 09:23
  • 1
    @Thorian93, in principle, /bin/echo could also treat -e differently, but in practice you probably have the echo from GNU coreutils or from Busybox, and both treat -e as an option. Though if you were to run /bin/echo --version with the coreutils echo... As for quotes, they don't do anything here, since they're a shell construct, and the options get handled in the utility itself. When echo gets to look at the options, the quotes aren't there any more. – ilkkachu Oct 07 '20 at 13:00
  • A deep dive into the echo utility. And I thought printing text would be easy. :) – Thorian93 Oct 08 '20 at 16:54