[Top][All Lists]

[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'
    def \
produces (as expected) the output:
    def \
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'
    def \
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 

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.

Geir Hauge in the comments of the question provided this patch to parse.y 
purporting to solve the issue: <http://sprunge.us/ZMAT>.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]