Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: Parameter assignment in a redirection word
- X-seq: zsh-users 30390
- From: Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx>
- To: "Mark J. Reed" <markjreed@xxxxxxxxx>
- Cc: Zsh Users <zsh-users@xxxxxxx>
- Subject: Re: Parameter assignment in a redirection word
- Date: Sun, 26 Oct 2025 11:16:07 -0700
- Archived-at: <https://zsh.org/users/30390>
- In-reply-to: <CAA=-s3zOJ62rhZspkaTEY6oua0Y2G=_ya=FgLi-6=ykw5LprOg@mail.gmail.com>
- List-id: <zsh-users.zsh.org>
- References: <aP3m4GfhFmVWI4nH@l380.home.lan> <a4bf296f46ce5dd477bb7cf128fce86231093701.camel@ntlworld.com> <CAA=-s3zOJ62rhZspkaTEY6oua0Y2G=_ya=FgLi-6=ykw5LprOg@mail.gmail.com>
On Sun, Oct 26, 2025 at 10:18 AM Mark J. Reed <markjreed@xxxxxxxxx> wrote:
>
> On Sun, Oct 26, 2025 at 13:01 Peter Stephenson <p.w.stephenson@xxxxxxxxxxxx> wrote:
>>
>> On Sun, 2025-10-26 at 10:16 +0100, Alexey Sukhoguzov wrote:
>> > Please help me to clarify this situation:
>> >
>> > $ (echo foo) > ${myvar:=tmpfile}
>> > $ echo ${myvar:-still unset}
>> > still unset
>>
>> It's a bit of a headbanger, and I don't see it explicitly documented, but
>> the main point of what's going on is that whenever zsh executes a command
>> that's not going to run in the main shell, any redirection is done after
>> the fork. This is really for convenience
>
> I'm not sure why the parameter expansion happens post-fork, though. The redirect, sure. But the parameter expansion should presumably happen before any of that stuff as part of parsing the command line. Why isn't the assignment already done by the time it forks the subshell?
There's a more subtle reason than just code convenience: The
redirection and the parameter substitution are semantically part of
the whole command including the subshell.
Consider that if you wrote
$ (echo foo) > ${myvar:=tmpfile} &
you would not (or at least I would not) expect the parameter
substitution to happen before the command was backgrounded. This
especially matters if you consider further expansions within the
parameter substitution:
$ (echo foo) > ${myvar:=$(sleep 30; echo tmpfile)} &
This was actually fixed several years later (a few years ago now) for
function definitions:
$ tempfoo() { echo foo } > ${myvar:=tmpfile}
The redirection and the substitution are both part of the function's
definition, not part of the creation of the function.
Messages sorted by:
Reverse Date,
Date,
Thread,
Author