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

Re: Bi-directional pipe

Guillaume Chazarain wrote:
> Is there a way to make a bi-directional pipe in zsh?
> That is, something like: foo | bar doing implicitly bar | foo, so
> foo stdin <- bar stdout and
> foo stdout <- bar stdin

With that sort of syntactically supported pipe, this depends on the OS.
Some, like Solaris, have bidirectional pipes by default.  On Solaris I
can do:

 ( exec 0<&1; echo I said foo; read line; print $line >/dev/tty) |
 ( exec 1>&0; read line; print $line >/dev/tty; echo You said bar; )
I said foo
You said bar

On Fedora Core 5, however, this gives me

I said foo
zsh: write error: bad file descriptor

If you are happy with something that looks a little bit like a
biderectional pipe, but one of the processes is actually asynchronous,
coprocesses are the simplest way of doing this (as mentioned in my
reponse zsh-users/10354 yesterday).  They contain a bidirectional pipe
as standard.  What's more, there's nothing to stop you from redirecting
stdin and stdout in the main shell from and to the coprocess.  The
following seems to work fine:

  coproc {
    read line
    print Coproc got $line >&2
    print Reply
  exec 1>&p 0<&p

  print Request
  read line

  print Main shell got $line >&2

Coproc got Request
Main shell got Reply

The only point of the business with fd 2 is to confirm that it's
working.  In summary, you can get what you want with:

    coproc {
       <foo code here>
    exec 1>&p 0<&p

    <bar code here>

You don't even need the subshell, necessary: that's just there to
protect the interactive environment from the redirection.

Peter Stephenson <pws@xxxxxxx>                  Software Engineer
CSR PLC, Churchill House, Cambridge Business Park, Cowley Road
Cambridge, CB4 0WZ, UK                          Tel: +44 (0)1223 692070

To access the latest news from CSR copy this link into a web browser:  http://www.csr.com/email_sig.php

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