0

So let's say we have this code:

a=$(echo -e "a\n\n\n")
echo "_${a}_"

the output is: _a_ which is kind of a surprise to me. Any ideas why this is happening?

tturbox
  • 115

1 Answers1

1

Because the bourne shell on which bash is based does this since 40 years ago (carried over through the change in syntax from backticks to $(...), and also required by the standard).

And so do all the other similar shells, including but not limited to zsh, ksh, yash, etc.

There's also no clear rationale for it (only post-hoc rationalizations). But it can be easily worked around:

a=$(some_command; echo x); a=${a%x}

The backticks works differently in csh, where the output is split to multiple words on runs of spaces (or newlines mixed with spaces when inside "..."), and any trailing newline(s) will turn into a single space:

printf 'a\n\n\n' > file
csh -c 'echo `cat file`b'
a b

Other programming languages who also have backticks/command substitution (like perl or php) do not have any of these quirks, and are capturing the exact output of the command:

perl -e 'print qx(printf "a\n\n")."b\n"'
a

b

  • See also the fish shell for a more useful command substitution behaviour in that regard (and rc to some extent). – Stéphane Chazelas Oct 26 '20 at 19:24
  • I've never used fish, feel free to add that info. I suppose that any language which works with lists instead of strings (rc, perl's qx in list context, etc) can do something more intelligent. –  Oct 26 '20 at 23:22