On systems where pipes are bidirectional (NetBSD, FreeBSD, SVR4-derived Unices (all those where pipes use STREAMS at least), but not Linux):
node foo.js <&1 | node bar.js >&0 On systems where they're not bidirectional (though of course on those where they are as well), besides the named pipe approach already mentioned, you can also use a socketpair which are bidirectional on all systems:
perl -MSocket -e ' socketpair(A, B, AF_UNIX, SOCK_STREAM, PF_UNSPEC); if (fork) { open STDIN, "<&A"; open STDOUT, ">&B"; exec "node", "foo.js"; } else { open STDIN, "<&B"; open STDOUT, ">&A"; exec "node", "bar.js"; }' Or two unnamed pipes, for instance using a coproc.
With zsh:
coproc node foo.js node bar.js <&p >&p ksh:
node foo.js |& node bar.js <&p >&p bash 4+:
coproc node foo.js node bar.js <&"${COPROC[0]}" >&"${COPROC[1]}" Or with yash's x>>|y pipe operator:
{ node foo.js <&3 3<&- | node bar.js 3<&-; } >>|3