All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jilles Tjoelker <jilles@stack.nl>
To: Oleg Bulatov <oleg@bulatov.me>
Cc: dash@vger.kernel.org
Subject: Re: heredoc and subshell
Date: Wed, 24 Feb 2016 00:18:44 +0100	[thread overview]
Message-ID: <20160223231843.GA55161@stack.nl> (raw)
In-Reply-To: <2978711456265264@web9h.yandex.ru>

On Wed, Feb 24, 2016 at 01:07:44AM +0300, Oleg Bulatov wrote:
> trying to minimize a shell code I found an unobvious moment with
> heredocs and subshells.

> Is it specified by POSIX how next code should be parsed? dash output
> for this code differs from bash and zsh.

> --- code
> prefix() { sed -e "s/^/$1:/"; }
> DASH_CODE() { :; }
> 
> prefix A <<XXX && echo "$(prefix B <<XXX
> echo line 1
> XXX
> echo line 2)" && prefix DASH_CODE <<DASH_CODE
> echo line 3
> XXX
> echo line 4)"
> echo line 5
> DASH_CODE

> --- bash 4.3.42 output:
> A:echo line 3
> B:echo line 1
> line 2
> DASH_CODE:echo line 4)"
> DASH_CODE:echo line 5

> --- dash 0.5.8 output:
> A:echo line 1
> B:echo line 2)" && prefix DASH_CODE <<DASH_CODE
> B:echo line 3
> line 4
> line 5

I think POSIX is clear that the bash/zsh behaviour is correct and the
dash behaviour is wrong. In XCU 2.6.3 Command Substitution, it says:

] With the $(command) form, all characters following the open
] parenthesis to the matching closing parenthesis constitute the
] command.

Therefore, the shell should not start reading the here-document
belonging to  prefix A <<XXX  while it is still inside the command
substitution  $(prefix B <<XXX.

Instead, the here-document belonging to  prefix B <<XXX  should be read.
The line ending the command substitution contains another <<
redirection; the here-documents are read in order of the <<
redirections.

In FreeBSD sh, another ash derivative, I fixed this in
FreeBSD SVN r208655,
https://github.com/freebsd/freebsd/commit/930ce3922652c50fc8b621b14b6238b325d7f16f

Interestingly, mksh parses this in yet another way. In unmodified form,
it fails with  here document 'XXX' unclosed. After appending an XXX
line, it outputs:

A:echo line 5
A:DASH_CODE
B:echo line 2)" && prefix DASH_CODE <<DASH_CODE
B:echo line 3
line 4

The here-document containing line 1 seems lost entirely.

The ksh93 93u+ 2012-08-01 from FreeBSD ports segfaults while executing
the script.

Concludingly, it seems unwise to rely on this construct in scripts to be
distributed.

-- 
Jilles Tjoelker

  parent reply	other threads:[~2016-02-23 23:28 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-02-23 22:07 heredoc and subshell Oleg Bulatov
2016-02-23 22:49 ` Eric Blake
2016-02-23 23:16   ` Eric Blake
     [not found]   ` <56CCE1E3.1060805-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2016-02-24 10:58     ` Joerg Schilling
     [not found]       ` <56cd8cd1.LdVYbpfe+0tQMm8I%Joerg.Schilling-8LS2qeF34IpklNlQbfROjRvVK+yQ3ZXh@public.gmane.org>
2016-02-24 12:27         ` Shware Systems
2016-02-24 12:32           ` Joerg Schilling
2016-02-24 20:27       ` Oleg Bulatov
2016-02-23 23:18 ` Jilles Tjoelker [this message]
2016-02-24  8:46   ` Thorsten Glaser

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20160223231843.GA55161@stack.nl \
    --to=jilles@stack.nl \
    --cc=dash@vger.kernel.org \
    --cc=oleg@bulatov.me \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.