Bash – Why doesn’t echo -e interpret a new line

bashnewlines

In bash, when I write this line

new_line="new\nline"

I get this as expected:

echo $new_line
new\nline

And this also works as expected:

echo -e $new_line 
new
line

as it says in a manual: -e enable interpretation of backslash escapes
However, this doesn't give me an interpreted \n new line character:

cur_log=$(who)
echo -e $cur_log
myuser pts/0 2017-01-19 07:10 (:0) myuser pts/1 2017-01-19 09:26 (:0) myuser pts/4 2017-01-19 09:14 (:0)

I thought that there is no new line character but if I write:

echo "$cur_log"

I get new line character interpreted.

myuser  pts/0        2017-01-19 07:10 (:0)
myuser  pts/1        2017-01-19 09:26 (:0)
myuser  pts/4        2017-01-19 09:14 (:0)

Why doesn't echo -e $cur_log interpret new line character but `echo -e $new_line does?

Best Answer

The reason is in your first variable (new_line), there is only an escape sequence (i.e. \n = backslash followed by n) which is passed unchanged to echo, while in the second one (cur_log), there are actual newlines which are stripped out by the shell being part of the IFS variable.

A new line is, under Unix/Linux, a single character which ASCII code is 10 (line-feed). When a file containing this character is displayed on screen, it is converted into two characters, carriage-return plus line feed (CR-LF), 10 + 13. When an editor like gedit is opens such a file, it stores each line separately. Linefeed is only used to detect the separation between two contiguous lines. \n is made of two characters, ASCII 92 + 110. If you edit a file containing occurrences of \n these two characters will be left unchanged and displayed as is, unlike real newlines.

Related Question