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

Re: command substitution: zsh waits until command exits

On Dec 3,  2:11am, Vincent Lefevre wrote:
} In which case, you should agree that a POSIX shell may do the
} substitution while the command has not terminated (if the standard
} output has been closed, of course).

OK, so I've now actually looked up the POSIX spec (whichever version
of it is online at opengroup.org).

I find that I don't agree, because 2.6.3 is not the only section that
deals with command substitution behavior.  A command substitution is
a subshell environment and you haven't created any asynchronous lists
so I think the shell must wait for the subshell to complete before
executing the next command.  E.g., in 2.9.1:

   If there is no command name, but the command contained a command
   substitution, the command shall complete with the exit status of
   the last command substitution performed.

If the shell were not obligated to wait, it wouldn't have the exit
status of the command substitution, and it would be unclear what is
meant by "the last performed."  It would be unreasonable to expect
that command substitutions behave asynchronously only in the absence
of a non-command-substitution in the command word position.

Also in 2.9.1, it says that

   2. The words that are not variable assignments or redirections shall
   be expanded ...

and then

   4. Each variable assignment shall be expanded ...

(If I previously knew that, I'd forgotten.)  Thus

  rm -f /tmp/first
  LAST=$(cat /tmp/first) printenv $(echo LAST & echo first > /tmp/first)

is IMO required to output "first", which again would not be determinable
if command substitution were not waited for.  Zsh gets this one right.

} Now, in both cases, zsh should document what it's doing.

I'm going to leave that decision up to someone else.  Documenting every
possible interpretation is a waste of bits and effort, but there'd be
something to be said for never repeating this discussion again.
} > echo $(coproc xterm -e 'zsh -fic "tty >&3 ; exec sleep 999999"' 3>&1 ;
} >        read -E <&p)
} > 
} > Or this, which doesn't rely on coproc:
} > 
} > echo $({ xterm -e 'zsh -fic "tty >&3 ; exec sleep 999999"' 3>&1 & } |
} >        read -E)
} Both are working. Is there one of them that is better?

Not really.  The second one is more portable, except for the reference to


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