0

I know $(cmd) captures the output of cmd into a string. However, it doesn't take care of the newline characters at the end.

Here's a demonstration:

a=$(echo x)
b=$(echo -n x)
[ "$a" = "$b" ] && echo equal

a and b capture outputs differed by a "\n" but these variables have the same value.

So my goal is still to capture the output of a command, but this time I want to preserve the last newline character(s) if there are any.

shouya
  • 2,863
  • 1
  • 24
  • 45
  • Would you please elaborate why you want to preserve the trailing newlines? Depends on your use case, maybe there is a simple workaround. – Lungang Fang Dec 28 '16 at 06:07

1 Answers1

2

Trailing newlines are removed

POSIX requires that the $(…) notation (or the equivalent using back-ticks) strips all trailing newlines from the end of the string that is captured.

§6.2.3 Command substitution

…, removing sequences of one or more <newline> characters at the end of the substitution.

There isn't a simple way around that, or to detect how many newlines were deleted.

Add a single newline to the end of the output

If you have Bash 4.x (4.3 tested) you can play with shell parameter expansion and the substring notation, and add a dummy line of output to the end of the original string (that's the echo n in this example):

$ x=$(echo pandemonium; blanklines 4; echo n)
$ echo "$x"
pandemonium




n
$ y=${x: 0: -1}
$ echo "$y"
pandemonium




$

When using Bash 3.2 (GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin16)) on macOS Sierra, the expansion for y generates an error:

$ y=${x: 0: -1}
-bash:  -1: substring expression < 0
$

See also Capturing multiple line output to a Bash variable.

Reliable and POSIX-compliant

Or you can use a simpler, more portable (POSIX-compatible) substitution suggested by the answer — as applied to this answer:

$ y=${x%n}
$ echo "$y"
pandemonium




$

Given that this works in strict POSIX shells and both Bash 3.x and 4.x, there's no need for the substring variant.

Community
  • 1
  • 1
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • Thanks for the explanation and the link. I got the answer I want at http://stackoverflow.com/a/5322980/1232832, good that it's more portable. – shouya Dec 28 '16 at 06:15