1

As per the graylog2 docs, I need to add this line to my rsyslog.conf:

$template GRAYLOGRFC5424,"<%pri%>%protocol-version% %timestamp:::date-rfc3339% %HOSTNAME% %app-name% %procid% %msg% \n"

I'm doing it programmatically when I spin up a server, so the command I've got going currently is:

sudo sh -c 'echo "\$template GRAYLOGRFC5424,\"<%pri%>%protocol-version% %timestamp:::date-rfc3339% %HOSTNAME% %app-name% %procid% %msg% \\\n\"" >> rsyslog.conf'

I'm escaping the dollar sign, both double quotes, and the backslash before the n. However, \n and \\n both write an actual newline to the file, but \\\n writes \n correctly. Why doesn't \\n work?

muru
  • 207,228
Zook
  • 134

1 Answers1

2

The problem seems to come from the builtin echo in dash (which is sh in Ubuntu by default), which seems to process its \ arguments differently from other implementations (/bin/echo and the builtin echo in Bash):

$ sh -c "echo '\\n'" 


$ sh -c "/bin/echo '\\n'"
\n
$ bash -c "echo '\\n'"
\n

This is not surprising, as using \ arguments in echo is non-standard:

http://pubs.opengroup.org/onlinepubs/009695399/utilities/echo.html

If the first operand is -n, or if any of the operands contain a backslash ( '\' ) character, the results are implementation-defined.

You should use printf instead of echo, like this:

printf '$template GRAYLOGRFC5424,"<%%pri%%>%%protocol-version%% %%timestamp:::date-rfc3339%% %%HOSTNAME%% %%app-name%% %%procid%% %%msg%% \\n"\n' | sudo tee -a rsyslog.conf

As a added bonus, using sudo tee to write to files as root instead of sudo sh -c + shell redirections makes the command cleaner, since the string is parsed only once (as an argument to printf) instead of twice (first as an argument to sh -c and then as an argument to echo).

fkraiem
  • 12,813