Shell Scripting – Automatic Transformation of Newlines in Variable Assignment

bcnewlinesshell

This came out of one of my comments to this question regarding the use of bc in shell scripting. bc puts line breaks in large numbers, e.g.:

> num=$(echo 6^6^3 | bc)
> echo $num
12041208676482351082020900568572834033367326934574532243581212211450\ 20555710636789704085475234591191603986789604949502079328192358826561\ 895781636115334656050057189523456

But notice they aren't really line breaks in the variable — or at least there are not if it is used unquoted. For example, in fooling around with more pipe in the assignment, e.g.:

num=$(echo 6^6^3 | bc | perl -pne 's/\\\n//g')

I realized that while there really is an \n in the bc output, checking echo $num > tmp.txt with hexdump shows the \n (ASCII 10) has definitely become a space (ASCII 32) in the variable assignment.

Or at least, in the output of unquoted $num >. Why is that?

As fedorqui points out, if you use quotes: echo "$num", you get newlines again. This is evident by examining the difference between echo $num > tmp.1 and echo "$num" > tmp.2 with hexdump; the former contains \ (backslash space) whereas the later contains \\n (backslash newline).

Best Answer

echo puts a space between each two arguments. The shell considers the newline in $num just a word separator (just like space).

lines="a
b
c"
set -x
echo $lines   # several arguments to echo
echo "$lines" # one argument to echo

See this answer (by the OP himself) for a more detailed explanation.

Related Question