It looks like this works.
function communicate(cmd::Cmd, input)
inp = Pipe()
out = Pipe()
err = Pipe()
process = run(pipeline(cmd, stdin=inp, stdout=out, stderr=err), wait=false)
close(out.in)
close(err.in)
stdout = @async String(read(out))
stderr = @async String(read(err))
write(process, input)
close(inp)
wait(process)
return (
stdout = fetch(stdout),
stderr = fetch(stderr),
code = process.exitcode
)
end
@show communicate(`cat`, "hello")
@show communicate(`sh -c "cat; echo errrr 1>&2; exit 3"`, "hello")