Re: Parameter assignment in a redirection word
Mikael Magnusson <[email protected]> Sun, 26 Oct 2025 17:32:21 +0100
| Newsgroups | gmane.comp.shells.zsh.devel,gmane.comp.shells.zsh.user |
|---|---|
| Message-ID | <CAHYJk3SLfRE1sNO6oNH4SJzEAzsH1rWFegVOqxmOF9AU4BKDmw@mail.gmail.com> |
On Sun, Oct 26, 2025 at 10:17 AM Alexey Sukhoguzov <[email protected]> wrote: > > Hi, > > Please help me to clarify this situation: > > $ (echo foo) > ${myvar:=tmpfile} > $ echo ${myvar:-still unset} > still unset > > Why $myvar is set in a subshell instead of a parent process in this > case? I was unable to find where it's documented, but I've checked > some other shells, and of course it turned out that zsh is not alone > here, at least bash is doing the same. OTOH, FreeBSD sh, oksh and > dash all seem to set the variable in a parent. I was thinking that > the latter is the only expected behavior, just like in > > $ echo foo > ${myvar:=tmpfile} > $ echo ${myvar:-still unset} > tmpfile > > which, by the way, works identically in all the shells that I've > tested. But after I tried > > $ (echo foo) | tee ${myvar:=tmpfile} > > and found that $myvar is set by a parent in zsh only, I'm not sure > what to expect any longer. Could anyone shed some light on what's > going on here? You'll find the same result if you use an external command as well, eg % /bin/echo > ${myvar:=tmpfile} You can force the expansion to happen in the current shell by using % { /bin/echo } > ${myvar:=tmpfile} or in your example % { ( echo ) } > ${myvar:=tmpfile} This isn't directly related, but the manual does have this to say about function definitions with redirections, In any of the forms above, a redirection may appear outside the function body, for example func() { ... } 2>&1 The redirection is stored with the function and applied whenever the function is executed. Any variables in the redirection are expanded at the point the function is executed, but outside the function scope. and in the case that the command is not found, the command_not_found_handler hook function is also run in the forked subshell (this is a bit more obvious though, we have to fork before we can try to exec the given command). -- Mikael Magnusson