IPC::Open3 will indeed simplify the first half of the code, which deals with the piping and the forking. Sorry for recommending the long winded solution :-( . It won't help with reading the outputs afterwards though, you still have to use a select loop to read interleaved input from both handles. That's why ikegami's recommentation of IPC::Run looks like it's even easier (thanks!).