0

When capturing BASH output, apparently BASH deletes trailing blank lines. For example, this:

$ VAR=$(echo -e '\n\n\n\n')

appears to leave VAR with a single newline, as can be seen in any number of ways, e.g. this one:

$ od -c <<< "$VAR"
0000000  \n
0000001

Interestingly, the phenomenon is not confined to capturing output. This somewhat devious experiment:

$ VAR="$(echo -e 'x\nx\nx\nx\n')"
$ VAR="${VAR//x/}"
od -c <<< "$VAR"
0000000  \n  \n  \n  \n
0000004

shows what I want / expect, creating 4 x/newline pairs and deleting the 4 intervening X's. It also verifies that shell variables can contain adjacent newlines, if there was any doubt. However this experiment:

V2="$VAR@$VAR"
od -c <<< "$V2"
0000000  \n  \n  \n   @  \n  \n  \n  \n
0000010

reveals that one newline is lost from the first occurrence of $VAR. NOT what I want or expect. And surprisingly NOT deleting the trailing newlines like the original problem capturing output.

In my application, I need the output to be precisely correct, but I have searched in vain for some way to turn off this "helpful" feature (or is it a bug?). I have not been able to play with this and find a workaround either, other than by using a kludge, e.g. capturing output that always includes an added line of non-blank text, such as:

VAR=$(some program ; echo "EOF")

This behavior is on a Debian 10 system with BASH 5.0.3, but I have also verified the same behavior on BASH 4.4.12. My guess is that it may have been around a long time.

I wonder if anyone knows how to get BASH to keep newlines in variables with the same integrity that it does every other character?

Al Whaley
  • 51
  • 1
  • 3
  • Yes, you are describing the well known and well documented behavior of command substitutions: they strip trailing newlines. The kludge is the conventional workaround. – chepner May 18 '20 at 17:20
  • Slightly less well-known is that a here-string always *adds* a newline, since it is intended to be equivalent to a one-line here document, which always ends in a newline. – chepner May 18 '20 at 17:22
  • And how about the example I listed where an interior newline is dropped on variable assignment with no command substitution? is that also a well known phenomenon? – Al Whaley May 18 '20 at 17:40
  • The newline was dropped when you *assigned* to `VAR`. `V2` has 3 newlines on either side of the `@`; the here string adds the 4th newline when you feed the value to `od`. – chepner May 18 '20 at 17:45
  • The "od" output suggests that there are 4 newlines in VAR unless you are suggesting that the <<< operation adds an extra newline?? I think you are saying that a variable assignment drops one extra trailing newline, even though command assignment drops many, and you are also saying that <<< adds one back? – Al Whaley May 18 '20 at 17:55
  • Yes, that is exactly what I am saying. The here string is equivalent to a here document with one line, and a here document always ends with a newline. Try `printf '%s' "$VAR" | od -c`. – chepner May 18 '20 at 18:08

0 Answers0