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

Two Unix to Perl questions about my Perl on Unix scripts:

I want to convert the following line in my Perl script to Perl instead of using the Unix system command.
system("cat $file | mailx -s 'Title' emailaddresshere");
I tried but doenst want to work:
open(FILE, "$file"); while (<FILE>) { print | mailx -s 'Title' myemailaddresshere; }


My next system question: I have the open STDERR, "/dev/null" in beginning of my script but still get an output from this in my script. Anyway to redirect this Unix system output to /dev/null area so I do not see the output on my screen??
system("/usr/sbin/ping $_");

Replies are listed 'Best First'.
Re: Unix system commands to Perl
by Abigail-II (Bishop) on Jul 09, 2002 at 18:03 UTC
    It's beyond me why you want to replace one line of code with 5 lines of code (and you're going to use an external program anyway....), but here it is:
    open my $fh => $file or die "Failed to open $file: $!\n"; open my $mh => "| mailx -s 'Title' email" or die "Failed to open pipe: + $!\n"; print $mh $_ while <$fh>; close $mh or die "Failed to close pipe: $!\n"; close $fh or die "Failed to close $file: $!\n";

    With open STDERR, "/dev/null" you open the handle for reading. Try opening it for writing, using open STDERR, "> /dev/null"

    Abigail

      Thank you.
Re: Unix system commands to Perl
by Aristotle (Chancellor) on Jul 09, 2002 at 18:46 UTC
    The first one is a Useless Use of cat. Since you're going through the shell anyway: system("mailx -s 'Title' emailaddresshere < $file"); Same applies for the second case - why bother monkeying in Perl if you're gonna shell out anyway? system("/usr/sbin/ping $_ 2> /dev/null"); ____________
    Makeshifts last the longest.
Re: Unix system commands to Perl
by hacker (Priest) on Jul 10, 2002 at 10:57 UTC
    Mail::Mailer sounds right for your first task here. Something like:
    use strict; use warnings; use Mail::Mailer; # mfile == 'Mail File' in context my $mfile = "somefile.txt"; # Override the default mailer found when the module was # installed (looks for 'mail', 'Mail' by default) my $mailer = Mail::Mailer->new("mail", "/usr/bin/mailx"); $mailer->open('From' =>'Joe User <juser@domain.com>', 'To' =>'Sally Seashells <ss@sshore.com>', 'Subject'=>'Do you sell seashells by the seashore?'); open (MFILE, "<$mfile") or die "Cannot open file: $!"; print $mailer MFILE; close MFILE; close($mailer) or die "Cannot close mailer: $!";

    For your second task, you could always use something like this:

    package Stderr; sub new { bless {} } # Turn off stderr sub stderr_off { open(SAVEERR, ">&STDERR"); close(STDERR); } # Turn on stderr sub stderr_on { open(STDERR, ">&SAVEERR"); close(SAVEERR); } 1;
Re: Unix system commands to Perl
by bronto (Priest) on Jul 10, 2002 at 16:48 UTC

    I would split your first system in two opens:

    open FILE,"< $file" or die $! ; open MAIL,"| mailx -s 'Title' emailaddresshere" or die $! ;

    Note: be sure to escape at signs (with \@) in emailaddresshere.

    Then you could easily do:

    # All-in-one-line while print MAIL while <FILE> ;

    (which is short for while (<FILE>) { print MAIL } or, more verbose, while ($_ = <FILE>) { print MAIL $_ })

    About the second question, this code snippet of mine:

    open STDERR,"/dev/null" ; warn "Test" ; system('echo TesT') ; system('echo TEST 1>&2') ;

    just print TesT, as one could expect, so I suppose that something in your code between the open and the system call breaks your redirection. What about using Net::Ping?

    Ciao!
    --bronto

    # Another Perl edition of a song:
    # The End, by The Beatles
    END {
      $you->take($love) eq $you->made($love) ;
    }