[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Non-expanding here-documents inside command substitution are subject to
From: |
Michael Homer |
Subject: |
Non-expanding here-documents inside command substitution are subject to newline joining |
Date: |
Sat, 11 Feb 2017 18:11:44 +1300 |
Bash has an unusual behaviour when a non-expanding here-document (<<‘EOT’) is
used inside $(…) command substitution. Newline joining occurs within the
document when it would not if the same document were not inside a command
substitution, while other shells do not perform it in either case.
This command:
cat <<'EOT'
abc
def \
ghi
jkl
EOT
produces (as expected) the output:
abc
def \
ghi
jkl
The backslash is uninterpreted and reproduced verbatim. Every Bourne-like shell
I can find has the same behaviour here.
If the same command is put inside command substitution instead, Bash (and
pdksh) behaves differently than the others, and performs newline joining to
have a single line in the middle “def ghi”. Given
x=$(cat <<'EOT'
abc
def \
ghi
jkl
EOT
)
In Bash, x now contains:
abc\ndef ghi\njkl
At least dash, ash, zsh, ksh93, BusyBox ash, mksh, and SunOS 5.10 POSIX sh
produce the verbatim contents of the here-document in both cases, and $x would
have four lines.
Using `cat <<'EOT' >&2` instead verifies that it is being in the command
substitution that creates the effect on the here-document, rather than the
process of substituting the output. An ordinary ( … ) subshell gives the same
non-joining behaviour everywhere. Only command substitution is different. I
think the verbatim non-joining behaviour of other shells is correct and Bash's
is not.
POSIX isn’t perfectly unambiguous here, but my intuition reading it is
consistent with everyone else’s behaviour rather than Bash’s. The relevant
parts of the specification I could find and more detail are given in
<http://unix.stackexchange.com/q/340923/73093>, and the original motivating
example was from someone trying to produce ASCII art inside command
substitution in an earlier question
<http://unix.stackexchange.com/q/340718/73093>.
This occurs in Bash 4.4 built from source on Debian x86_64 and OS X, Debian
stable’s 4.3, Apple’s 3.2, and unknown versions used by several other
participants in those questions. 3.2 also processes backticks inside the
here-document, but the later versions do not.
I’m filing this as a Bash bug because of the inconsistency with the consensus
behaviour of other shells. It’s arguable that it is a permitted behaviour, or
even required, so if it’s preferred I’ll instead raise it for a formal
interpretation to clarify what portable scripts should be able to rely on.
Fix:
Geir Hauge in the comments of the question provided this patch to parse.y
purporting to solve the issue: <http://sprunge.us/ZMAT>.
- Non-expanding here-documents inside command substitution are subject to newline joining,
Michael Homer <=