Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: command substitution: zsh waits until command exits

On 2007-11-30 07:37:19 -0800, Bart Schaefer wrote:
> On Nov 30,  2:39pm, Vincent Lefevre wrote:
> }
> } but doesn't say when zsh does the substitution and runs the main
> } command (it should be clarified).
> Look earlier in that man page.  Almost the first thing it says is:
>    The following types of expansions are performed in the indicated
>    order in five steps:
> with "Command Substitution" listed as happening at the third step,
>    ... in left-to-right fashion.
> (i.e., in the order it is found when scanning the command line).

This doesn't answer my question (see below).

> } For instance, with the following
> } command
> } 
> }   echo $(echo foo; exec >&-; sleep 2)
> } 
> } zsh waits for 2 seconds before outputting 'foo'. However, since the
> } standard output fd of the substituted command has been closed, I assume
> } that zsh should be able to replace $(echo foo; exec >&-; sleep 2) by
> } 'foo' and run the main command before the command inside $(...) exits.
> } Is this a bug?
> That really has nothing to do with "when zsh does the substitution"

By "when zsh does the substitution", this includes the question
whether zsh does the substitution before or after the command exits.
For instance, zsh could start commands in the left-to-right fashion
(I assumed asynchronously), but could replace the $(...) in some
arbitrary order, once it knows the result, i.e. once the standard
output is closed.

> and everything to do with job control. It's not a bug.
> } Otherwise, is there a way to do what I wish (without temporary files)?
> Sure -- background the command yourself, e.g.:
>   echo $({ echo foo ; exec >&- ; sleep 2; echo bar >/dev/tty } &)

It wasn't clear that zsh didn't do this itself. With process
substitution, the man page says that "the shell runs process list
asynchronously", and I thought this was the same with command
substitution, since this is very similar.

BTW, in fact, I had tried to background the command with xterm, but
this didn't work. Probably because of this:

> That one is a bit tricky and the problem is that xterm doesn't close
> the descriptors that it passes through to the command it's running, so
> even when "exec 3>&-" runs *inside* the xterm, the descriptor is still
> open.  So you have to run xterm in a way that it's descriptors don't
> matter.  Something like:
>   echo $(coproc xterm -e 'tty >&3; sleep 999999' 3>&1 ; read -E <&p)

OK, thanks. But is there any reason why Ctrl-C doesn't work in the

Vincent Lefèvre <vincent@xxxxxxxxxx> - Web: <http://www.vinc17.org/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.org/blog/>
Work: CR INRIA - computer arithmetic / Arenaire project (LIP, ENS-Lyon)

Messages sorted by: Reverse Date, Date, Thread, Author