sh: Allow terminating a heredoc with a terminator at EOF without a newline.

This is sometimes used with eval or old-style command substitution, and most
shells other than ash derivatives allow it.

It can also be used with scripts that violate POSIX's requirement on the
application that they end in a newline (scripts must be text files except
that line length is unlimited).

Example:
v=`cat <<EOF
foo
EOF`
echo $v

This commit does not add support for the similar construct with new-style
command substitution, like
v=$(cat <<EOF
foo
EOF)
This continues to require a newline after the terminator.
This commit is contained in:
Jilles Tjoelker 2011-05-20 16:03:36 +00:00
parent df1bc9de7c
commit 85307c9ed9
2 changed files with 31 additions and 3 deletions

View File

@ -1513,10 +1513,12 @@ checkend: {
p = line;
for (q = eofmark + 1 ; *q && *p == *q ; p++, q++);
if (*p == '\n' && *q == '\0') {
if ((*p == '\0' || *p == '\n') && *q == '\0') {
c = PEOF;
plinno++;
needprompt = doprompt;
if (*p == '\n') {
plinno++;
needprompt = doprompt;
}
} else {
pushstring(line, strlen(line), NULL);
}

View File

@ -0,0 +1,26 @@
# $FreeBSD$
failures=''
check() {
if eval "[ $* ]"; then
:
else
echo "Failed: $*"
failures=x$failures
fi
}
check '`cat <<EOF
foo
EOF` = foo'
check '"`cat <<EOF
foo
EOF`" = foo'
check '`eval "cat <<EOF
foo
EOF"` = foo'
test "x$failures" = x