* added IPC::Open3 examples from Benjamin Goldberg

Index: perlfaq8.pod
===================================================================
RCS file: /cvs/public/perlfaq/perlfaq8.pod,v
retrieving revision 1.9
diff -u -d -r1.9 perlfaq8.pod
--- perlfaq8.pod        21 Jun 2002 04:33:43 -0000      1.9
+++ perlfaq8.pod        21 Jun 2002 04:48:43 -0000
@@ -620,6 +620,67 @@
 script's STDOUT and STDERR, unless the system() command redirects them.
 Backticks and open() read B<only> the STDOUT of your command.
 
+You can also use the open3() function from IPC::Open3.
+
+To capture a program's STDOUT, but discard it's STDERR:
+
+    use IPC::Open3;
+    use File::Spec;
+    use Symbol qw(gensym);
+    open(NULL, ">", File::Spec->devnull);
+    my $pid = open3(gensym, \*PH, ">&NULL", "cmd");
+    while( <PH> ) { }
+    waitpid($pid, 0);
+
+To capture a program's STDERR, but discard it's STDOUT:
+
+    use IPC::Open3;
+    use File::Spec;
+    use Symbol qw(gensym);
+    open(NULL, ">", File::Spec->devnull);
+    my $pid = open3(gensym, ">&NULL", \*PH, "cmd");
+    while( <PH> ) { }
+    waitpid($pid, 0);
+
+To capture a program's STDERR, and let it's STDOUT go to our own STDERR:
+
+    use IPC::Open3;
+    use Symbol qw(gensym);
+    my $pid = open3(gensym, ">&STDERR", \*PH, "cmd");
+    while( <PH> ) { }
+    waitpid($pid, 0);
+
+To read both a command's STDOUT and its STDERR separately, you can
+redirect them to temp files, let the command run, then read the temp
+files:
+
+    use IPC::Open3;
+    use Symbol qw(gensym);
+    use IO::File;
+    local *CATCHOUT = IO::File->new_tempfile;
+    local *CATCHERR = IO::File->new_tempfile;
+    my $pid = open3(gensym, ">&CATCHOUT", ">&CATCHERR", "cmd");
+    waitpid($pid, 0);
+    seek $_, 0, 0 for \*CATCHOUT, \*CATCHERR;
+    while( <CATCHOUT> ) {}
+    while( <CATCHERR> ) {}
+
+But there's no real need for *both* to be tempfiles... the following
+should work just as well, without deadlocking:
+
+    use IPC::Open3;
+    use Symbol qw(gensym);
+    use IO::File;
+    local *CATCHERR = IO::File->new_tempfile;
+    my $pid = open3(gensym, \*CATCHOUT, ">&CATCHERR", "cmd");
+    while( <CATCHOUT> ) {}
+    waitpid($pid, 0);
+    seek CATCHERR, 0, 0;
+    while( <CATCHERR> ) {}
+
+And it'll be faster, too, since we can begin processing the program's
+stdout immediately, rather than waiting for the program to finish.
+
 With any of these, you can change file descriptors before the call:
 
     open(STDOUT, ">logfile");

Reply via email to