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

Re: command substitution: zsh waits until command exits

On Dec 2,  4:22pm, Vincent Lefevre wrote:
} Subject: Re: command substitution: zsh waits until command exits
} On 2007-12-01 21:07:44 -0800, Bart Schaefer wrote:
} > Process substitution wouldn't work at all if it were synchronous.
} This could work: for <(...), zsh could start the process, redirecting
} its output to a temporary file, and once the process has terminated,
} zsh could run the command with a normal redirection, and clean up at
} the end.

Yes, it could work that way, but if that's what you want, <=(...) is
there for you.
} The substituted command doesn't need to be finished to be able to
} build the argument list: its standard output just needs to be closed
} (which is what I did in my example).

This discussion is getting sort of cyclical.  It doesn't work that way.
It doesn't work that way in any other shell, either, never has, and
although I don't have it handy I'm pretty sure the POSIX spec would
prohibit it from working that way.

} This is the same thing with a pipe

Mechanically, maybe, but not semantically.  The "|" character is one
of those special syntatic elements that invokes asynchronous behavior.
$(...) or `...` happens NOT to be such a syntactic element.  <(...) IS
such an element, as are "&" and "coproc".

You'll also note that even though "cat" finishes in

   { echo ab; exec 1>&-; sleep 5 } | cat

the parent shell does not return to a prompt until the sleep finishes.
That's the real analogy to what's happening with $(...).

}   echo $(coproc xterm -e 'stty -a ; tty >&3 ; sleep 999999' 3>&1 ;
}          read -E <&p)
} outputs
} speed 38400 baud; rows 60; columns 80;
} intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>;
} in the xterm, but Ctrl-C still doesn't work.

Hence my speculation that something is setting the SIGINT handler to
SIG_IGN and nothing else is ever resetting it.  I don't immediately know
*what* is ignoring SIGINT.

This seems to do what you want by restoring the interactive handlers:

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)

The zsh -fic is still needed there so I think it may be $(...) that's
ignoring interrupts, which possibly it should not do.

} > Incidentally I use this little function all the time:
} > 
} > gdbterm () {
} >     xterm -title GDBterm -e sh -c 'exec xterm -e gdb --tty=$(tty) '"$*"
} > }
} but that's specific to gdb. And why starting two xterms?

GDB runs in one, and the command run by GDB uses the other for I/O, and
both of them close together when I exit GDB because the I/O xterm is the
parent waiting for completion of the GDB xterm.


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