Dru has asked for the wisdom of the Perl Monks concerning the following question:

Greetings fellow monks,

I have compressed log files that I open like so:
open (FILE, "zcat $file |")
but now I need the ability to output the results to more. I read the documentation on open and perlipc but I'm still not clear on how to proceed. Should I be looking to use IPC::Open2 or IPC::Open3?

Mucho Gracias for any assistance.
-Dru

Replies are listed 'Best First'.
Re: Open a Compressed File and Piping to More
by Roy Johnson (Monsignor) on Mar 17, 2004 at 15:46 UTC
    open(STDOUT, '| more') or die;

    The PerlMonk tr/// Advocate

      Also keep in mind that if you might have other output after what's paged is done it'd be a good idea to keep the original STDOUT around.

      local( *SAVESTDOUT ); open( SAVESTDOUT, ">&STDOUT" ) or warn "Can't dup STDOUT: $!\n"; my $pager = $ENV{PAGER} || 'more'; open( STDOUT, "| $pager" ) or die "Can't open pipe to $pager: $!\n"; while( <COMPRESSED> ) { print "Wubba: $_" if /wubba/i; } close( STDOUT ); open( STDOUT, ">&SAVESTDOUT ) or warn "Can't dup SAVESTDOUT: $!\n";

      Or just use a different handle than STDOUT for your output to begin with (possibly using one-arg select() to change the default output handle as necessary).

Re: Open a Compressed File and Piping to More
by Abigail-II (Bishop) on Mar 17, 2004 at 16:21 UTC
    No, IPC::Open2 and IPC::Open3 are used if you want to open 2 or 3 pipes to the same process. (STDIN, STDOUT, STDERR). In your case, I'd do something like:
    open my $in => "zcat $file |" or die; open my $out => "| more" or die; while (<$in>) { # do something. print $out $_ or die; } close $in or die; close $out or die;

    Abigail

Re: Open a Compressed File and Piping to More
by graff (Chancellor) on Mar 18, 2004 at 06:38 UTC
    It might be mutually instructive to know a little more about the context around this problem. Why do you need to do this from within a perl application, as opposed to simply doing it in a shell window as a normal command line?

    For example, if you happen to be using unix/x-windows, and the perl script is providing some convenient controls on file selection, then a nice work-around within your perl script could be:

    ... system( "xterm -e 'zcat $file | less' &" ); ...
    That fires up a fresh xterm running as a background job (control returns to the perl script while the xterm stays up); the xterm is running a command where the output of zcat is being fed to "less" (not more); when the user hits "q" or some other means for quitting less, the xterm goes away, but until then, the user can browse the file contents indefinitely, and continue using the perl script to bring up more files in other windows, as needed. I use this strategy a lot.

    I expect there's a way to do the same thing with ms-windows -- i.e. without x-windows/xterm -- assuming you have ms-win versions of a unix-like shell and the command line tools involved.