in reply to Command Line Program Wrapper

i've made some modifications to your code to make it a bit safer, and to capture more output:

== your initial code didn't check for a valid set of commands, so someone could have run malicious code and sent you an email after the fact. i created a set of valid commands to prevent this
== i added error checking all around, including creation of mail object, io handles, etc.
== i seperated the output to STDERR and STDOUT into different streams, for better reporting
== i captured the exit code and process id, just to be complete
== i sent output to the screen as well as in an email.

see below.

#!/usr/local/bin/perl -w use strict; $|++; use constant EMAIL => 'you@yourdomain.com'; use constant SERVER => 'mail.yourdomain.com'; use IO::Handle; use IPC::Open3; use Net::SMTP; use Mail::Mailer; # create list of valid commands (put your commands in here!) # stop malicious usage!!! my $valid_commands = "(backup_nt|backup_unix|backup_linux)"; my $n = "\n"; # get command from command line, display usage if error my $cmd = shift || die("usage: $0 $valid_commands [opts]\n"); # verify command is valid die "invalid command: $cmd" unless($cmd =~ /$valid_commands/); my $cmdopts = join ' ', @ARGV; my $mail = Net::SMTP->new( SERVER ) || die("cannot create mail server! $!"); $mail->to( EMAIL ); $mail->mail( 'root@yourdomain.com' ); $mail->data(); my (@output, $test, $pid, $exitcode); # create local io handles, fail if open fails my $OUTPUT = new IO::Handle; # create handle for STDOUT my $OUTERR = new IO::Handle; # create handle for STDERR my $IN = new IO::Handle; # create handle for STDIN open( $OUTPUT, ">&STDOUT" ) or # duplicate STDOUT die "Can't dup STDOUT to OUTPUT: $!$n"; open( $OUTERR, ">&STDERR" ) or # duplicate STDERR die "Can't dup STDERR to OUTERR: $!$n"; open( $IN, "<&STDIN" ) or # duplicate STDIN die "Can't dup STDIN to IN: $!$n"; $test = eval # execute $cmd, redirecting to new +handles, { # and capture the process id $pid = open3($IN, $OUTPUT, $OUTERR, "$cmd $cmdopts") or die($!); my $junk = waitpid(-1,0); # don't care about return val }; $exitcode = $? >>8; # $? is exitcode of $s ( from waitp +id() ) # format output for mailing push @output, " -> Result:" . $n; push @output, $_ while(<$OUTPUT>); push @output, " -> Errors:" . $n; push @output, $_ while(<$OUTERR>); push @output, " -> Exit Code: " . $exitcode . $n; push @output, " -> Process ID: " . $pid . $n; close $OUTPUT; # close OUTPUT handle close $OUTERR; # close OUTERR handle close $IN; # close IN handle # send error if eval failed, otherwise send output if ($@) { $mail->datasend("command '$cmd $cmdopts' could not be executed: $@ +\n"); print "command '$cmd $cmdopts' could not be executed: $@\n"; } else { $mail->datasend( " -> Command: $cmd $cmdopts" , $n, join('', @output), $n, ); print( " -> Command: $cmd $cmdopts" , $n, join('', @output), $n, ); } $mail->datasend; $mail->quit; exit 0;

~Particle