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

Hi Monks, I have a script asdf.pl and when i run it, it will output data to screen (STDOUT). But I want to design the script such that if i put "asdf.pl -o asdf.list" , it should output everything to a file instead. Note : cannot do asdf.pl >! asdf.list in the command line

Replies are listed 'Best First'.
Re: Filehander Question
by Limbic~Region (Chancellor) on Oct 07, 2004 at 15:23 UTC
    EchoAngel,
    One way to do this is to make STDOUT the default, but allow the user to overide.
    #!/usr/bin/perl use strict; use warnings; use Getopt::Std; my $opt = {}; Get_Args( $opt ); my $fh; if ( $opt->{o} ) { open ( $fh, '>', $opt->{o} ) or die "Unable to open $opt->{o} for +writing : $!"; } else { open ( $fh, '>&', *STDOUT ) or die "Unable to dup STDOUT : $!"; } select $fh; $| = 1; print "foo bar\n"; sub Get_Args { my $opt = shift; my $Usage = qq{Usage: $0 [options] -h : This help message. -o : Output file - STDOUT by default } . "\n"; getopts( 'ho:' , $opt ) or die $Usage; die $Usage if $opt->{h}; }

    Cheers - L~R

    Note: The lexical FD, 3 arg open, and specifically '>&' are new in more recent versions of Perl. It is trivial to modify if you want to support older versions

      Your code has a side effect.
      print $fh ('test');
      and
      print('test');
      both end up in the file, when a filename is specified. I don't think that was your intention.

      To set auto-flushing, do
      { my $f = select($fh); $|=1; select($f); }
      instead of
      select($fh); $|=1;

        ikegami,
        That isn't a side effect, that is the primary effect. I interpreted EchoAngel's request as I don't want to have to change anything other than -o "somefile" to get all my existing prints to DWIM. I guess you took my comment in the CB about needing select to do auto-flushing to mean that is the only reason I did it - sorry.

        Cheers - L~R

Re: Filehander Question
by Fletch (Bishop) on Oct 07, 2004 at 15:18 UTC

    So, erm, do that. Read perldoc perlopentut and perldoc -f open. Read the docs for Getopt::Std or Getopt::Long. If you're given a filename, open a handle on it; if not, dup STDOUT.

    my $fh; if( $filename ) { # open file, put handle in $fh } else { # dup STDOUT, put handle in $fh } print $fh "wubba wubba\n"; close( $fh ); exit( 0 );

    Update: expanded the exercise-for-the-reader comments some.

Re: Filehander Question
by ikegami (Patriarch) on Oct 07, 2004 at 15:24 UTC

    First, get the filename from the command line (using the Getopt::Std or Getopt::Long module, perhaps.)

    # Redirect STDOUT. if ($filename) { open(STDOUT, '>', $filename) or die("Can't open redirect STDOUT: $!\n"); } print(...); # Goes to file if one was specified, else STDOUT.

    -or-

    # Use select. if ($filename) { open(FILE, '>', $filename) or die("Can't open $filename: $!\n"); select(FILE); } print(...); # Goes to file if one was specified, else STDOUT.

    -or-

    # If you want to output to STDOUT and to the file, # create a handle which may point to STDOUT. if ($filename) { open(FILE, '>', $filename) or die("Can't open $filename: $!\n"); } else { open(FILE, ">&STDOUT"); or die("Can't dup STDOUT: $!\n"); } print FILE (...); # Goes to file if one was specified, else STDOUT. print(...); # Goes to STDOUT.
Re: Filehander Question
by BrowserUk (Patriarch) on Oct 07, 2004 at 15:56 UTC
    Note : cannot do asdf.pl >! asdf.list in the command line.

    Idle curiosity. Why not?


    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "Think for yourself!" - Abigail
    "Memory, processor, disk in that order on the hardware side. Algorithm, algorithm, algorithm on the code side." - tachyon
      the guy above me said he doesn't want that way lol

        Let's see:

        asdf.pl > asdf.lst

        versus

        asdf.pl -o asdf.lst

        Hmmm! :?


        Examine what is said, not who speaks.
        "Efficiency is intelligent laziness." -David Dunham
        "Think for yourself!" - Abigail
        "Memory, processor, disk in that order on the hardware side. Algorithm, algorithm, algorithm on the code side." - tachyon