I sometimes record some modules as possible "future save-the-day solutions" when I read about them, mostly on Perl Monks. One of these modules is IPC::Open3, but I'd take more care in ensuring these safe nets.
IPC::Open3 is useful when you want complete input/output control on a spawned process, i.e. when you have to control its STDIN, STDOUT and STDERR as well. The interface is quite straightforward:
$pid = open3(\*WTRFH, \*RDRFH, \*ERRFH, 'some cmd and args', 'optarg', ...); my($wtr, $rdr, $err); $pid = open3($wtr, $rdr, $err, 'some cmd and args', 'optarg', ...);
One thing that the docs state quite clearly is the following:
If ERRFH is false, or the same file descriptor as RDRFH, then STDOUT and STDERR of the child are on the same filehandle.
It's easy (at least for me) to overlook this, and you can imagine my surprise discovering that all the STDERR of the spawned process goes straight to STDOUT, and the filehandle for $err is undefined. What's not so easy is to discover how one can address this issue. IMHO, the "Do What I Mean" mantra has been spectacularly betrayed here, where I would expect a brand new handle to be created for me. Just like $wtr and $rdr, you know. Just like the filehandle in open().
Thanks to this thread, I discovered one solution to the problem: gensym. Here's a working snippet, at last:
#!/usr/bin/perl # see also http://www.perlmonks.org/?node_id=150748 use strict; use warnings; use IPC::Open3 qw( open3 ); use Symbol; # provides gensym my ($in, $out, $err); $err = gensym(); # Aha! This was what I was after my $pid = open3($in, $out, $err, '/bin/ls', '/path/to/inexistent', '/tmp') or die "open3(): $!"; my @emsg = <$err>; # The error comes from here print {*STDOUT} "process STDERR: @emsg\n" if @emsg; my @omsg = <$out>; # Output for existing stuff print {*STDOUT} "process STDOUT @omsg\n" if @omsg; __END__ poletti@PolettiX:~/sviluppo/perl$ perl open3-gensym.pl process STDERR: /bin/ls: /path/to/inexistent: No such file or directory process STDOUT /tmp: prova v206821 v206828 v274678 v279868 v283182
Something to remember well for the future...