Dash, command substitution not inserting newline?

Basically, this is the issue:

$ echo Hello"$(printf '\n')"World
HelloWorld

What did I overlook ?


This behavior is actually part of the POSIX specification for command substitution:

The shell shall expand the command substitution by executing command in a subshell environment (see Shell Execution Environment) and replacing the command substitution (the text of command plus the enclosing "$()" or backquotes) with the standard output of the command, removing sequences of one or more characters at the end of the substitution. Embedded characters before the end of the output shall not be removed; however, they may be treated as field delimiters and eliminated during field splitting, depending on the value of IFS and quoting that is in effect. If the output contains any null bytes, the behavior is unspecified.

So the normal quoting rule "$(...)" only preserves non-trailing newlines.

Some suggestions for preserving trailing newlines are given in shell: keep trailing newlines ('\n') in command substitution

See also When printing a variable that contains newlines, why is the last newline stripped? for discussion of the rationale behind the specification.